Pytest - Python 單元測試 教學
TL;DR
Test-Driven Design的作者 Kent-Beck說過 “Write tests until fear is transformed into boredom.”
在進行重構時,每次最害怕的莫過於改了一個地方,其他地方就壞掉了。這時候,單元測試就是你的好幫手。你可以透過點擊一下按鈕,就能知道你的程式碼是否有問題。以前都寫java的單元測試,現在開始學習機器學習的相關領域,覺得也要培養寫測試的習慣。
Pytest vs Unittest
以 Python 後端來說,眾多測試框架裡最熱門的當屬下面兩者:
- 第三方 Pytest
- Pytest 不需要把測試的 function 封裝在類別(class)之中,你可以更加自由地定義你的測試案例
- e.g. 不需要放unittest.TestCase
class TestAddition(unittest.TestCase)
- e.g. 不需要放unittest.TestCase
- 僅僅需要在測試 .py 檔以及檔案裡的測試 function 加上
test_
的前綴,pytest 就可以自動去辨認並執行這些測試腳本- e.g. 直接定義function 並且加上test的前綴
test_add_function()
- e.g. 直接定義function 並且加上test的前綴
- Pytest 不需要把測試的 function 封裝在類別(class)之中,你可以更加自由地定義你的測試案例
- Python 內建的 Unittest
- Unittest 在建立測試案例時,需要將程式寫在 Test 作為命名開頭的類別 (class) 中,並且要繼承 unittest.TestCase 這個類別
- 編寫上雖較為嚴謹,但也較不直覺、需要較多步驟
Unittest
1 | import unittest |
pytest
1 | def add(a, b): |
這篇文章主要介紹 Pytest,因為 Pytest 是一個功能更強大、更簡潔的測試框架,並且近年來,pytest 已成為 Python 測試最受歡迎的選擇之一。
安裝教學
開啟終端機並寫入:
1 | pip install pytest |
在開始寫測試之前,這邊想要先介紹一下 pytest 的基本規則:
- 測試檔案必須以
test_
開頭 - 測試函數必須以
test_
開頭 - 測試函數中的斷言必須使用
assert
關鍵字
Test資料夾結構
使用 Pytest 測試框架進行測試時,需要按照特定格式擺放檔案。並沒有唯一正確的格式,身為一個廣泛使用的測試框架,Pytest 可依照使用者的需求自行指定。
1 | | |
從上述的架構我們可以掌握幾個原則 :
- 主要的程式碼會統一放在
src/
(也有人稱為app
,lib
或直接用模組的用途命名) - 測試用的程式碼則統一放在 tests 資料夾
- 通常測試用的程式碼會以 test_xxx.py 命名 (我自己的習慣是直接對應到 src/ 中的模組)
fixture
在unittest中我們必須要在每個測試函數中重複的初始化一些變數,或是在運行測試函試之前的工作,但是有可能很多測試函式要設定的參數都很雷同,使用unittest會讓測試程式碼變得冗長。而在pytest中,我們可以使用fixture來解決這個問題,讓多個function可以共用一些初始化變數。
1 | import unittest |
但是在pytest中可以透過fixture來設定測試前的設定,使得一個function的資源可以被其他測試function所使用。
1 | import pytest |
如果想要多個function共用一些變數還可以這樣寫
1 | # 定義一個class裡面放所有變數 |
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Shannon's Blog 🐟 技術 | 生活 | 旅行! 如果你覺得我的文章有幫助,希望你可以到我的 github 給我一個 star ⭐️ Shannon Blog Repo
評論