編寫、執行與測試程式碼¶
要修復錯誤或實作新功能,您將需要撰寫一些新程式碼。
開始編寫程式碼前,請確保已建立開發環境,並在分支上進行開發。
我們有一份 程式碼風格指南,其中概述了為 BeeWare 編寫程式碼的準則。
測試驅動開發¶
確保程式碼能如預期運作的好方法,是先撰寫一個測試案例來驗證它。這個測試案例最初應該會失敗,因為它所測試的程式碼尚未存在。接著,您可以撰寫必要的程式碼變更以讓測試通過,並確信您所寫的程式碼確實解決了您預期要解決的問題。
執行您的程式碼¶
寫完程式碼後,您需要確保它能夠執行。您必須手動執行程式碼,以驗證其運作結果是否符合預期。若尚未進行,建議您為所做的變更撰寫測試案例;如前所述,若程式碼被註解掉或不存在,此測試應會失敗。
您將把測試案例新增至測試套件中,以便它能與其他測試一併執行。下一步是執行該測試套件。
執行測試 及覆蓋率¶
BeeWare 使用 tox 來管理測試流程,並使用
pytest 來管理其自身的測試套件。
預設的 tox 指令包含執行:
- 預提交鉤子
towncrier版本說明檢查-
文件檢查
-
適用於各 Python 版本的測試套件
-
程式碼覆蓋率報告
這基本上就是您提交拉取請求時,CI 所執行的流程。
若要執行完整的測試套件,請執行:
(.venv) $ tox
(.venv) $ tox
(.venv) C:\...>tox
執行完整的測試套件可能需要一段時間。您可以透過並行執行 tox,或執行 tox p(或 tox
run-parallel)來大幅加快速度。當您並行執行測試套件時,在執行過程中獲得的進度回報會較少,但測試執行結束後仍會收到任何發現問題的摘要。您應該會看到一些輸出訊息,顯示測試已執行。
您可能會看到 SKIPPED 個測試,但絕不應收到任何 FAIL 或 ERROR
的測試結果。我們會在合併每個修補程式之前執行完整的測試套件。若該過程發現任何問題,我們便不會合併該修補程式。如果您確實發現測試錯誤或失敗,那可能是您的測試環境有異常,或是您發現了我們尚未遇過的邊界案例——無論是哪種情況,請務必告知我們!
除了測試通過之外,這應該會顯示 100% 測試覆蓋率。
執行測試變體¶
針對多個 Python 版本執行測試¶
預設情況下,許多 tox 指令會嘗試多次執行測試套件,針對 BeeWare 所支援的每個 Python
版本執行一次。不過,要達成此目的,您的電腦上必須已安裝每個 Python 版本,且 tox 的 Python
偵測
程序能夠找到這些版本。一般來說,如果 PATH 能偵測到某個 Python 版本,那麼 tox 應該就能找到並使用它。
僅執行測試套件¶
如果您正在對新功能進行快速迭代,則無需執行完整的測試套件;您可以僅執行單元測試。要執行此操作,請執行:
(.venv) $ tox -e py
(.venv) $ tox -e py
(.venv) C:\...>tox -e py
執行部分測試¶
預設情況下,tox 會執行單元測試套件中的所有測試。當您開發新測試時,可能需要「僅」執行該單一測試。要達成此目的,您可以將 任何 pytest
指定符
作為參數傳遞給 tox。這些測試路徑是相對於 briefcase 目錄的。例如,若要僅執行單一檔案中的測試,請執行:
(.venv) $ tox -e py -- tests/path_to_test_file/test_some_test.py
(.venv) $ tox -e py -- tests/path_to_test_file/test_some_test.py
(.venv) C:\...>tox -e py -- tests/path_to_test_file/test_some_test.py
即使只執行測試套件的一部分,您仍會收到覆蓋率報告——但覆蓋率結果僅會顯示您所執行的特定測試所執行的程式碼行。
執行特定 Python 版本的測試套件¶
預設情況下,tox -e py 會使用您電腦上解析為 python 的任何解釋器來執行。如果您安裝了多個 Python
版本,且希望從已安裝的版本中測試特定版本,您可以指定要使用的特定 Python 版本。例如,若要在 Python 3.10 上執行測試套件,請執行:
(.venv) $ tox -e py310
(.venv) $ tox -e py310
(.venv) C:\...>tox -e py310
若要在命令列中加入 -- 以及測試規格,即可執行 測試子集。
不包含覆蓋率的測試套件(快速)¶
預設情況下,tox 會以單執行緒模式執行 pytest
測試套件。您可以透過並行執行測試套件來加快執行速度。由於在子程序中擷取覆蓋率較為複雜,此模式不會產生覆蓋率檔案。若要以「快速」模式執行單一 Python
版本,請執行:
(.venv) $ tox -e py-fast
(.venv) $ tox -e py-fast
(.venv) C:\...>tox -e py-fast
若要在命令列中執行 測試子集,請在命令列中加入 -- 以及測試規格;若要使用 特定的 Python
版本,請在測試目標中加入該版本(例如,加入 py310-fast 以在
Python 3.10 上執行 fast)。
程式碼覆蓋率¶
BeeWare 的程式碼庫維持 100% 的分支覆蓋率。當您在專案中新增或修改程式碼時,必須新增測試程式碼,以確保所做的任何變更都能獲得測試覆蓋。
然而,BeeWare 同時支援多個平台以及多個 Python 版本,因此無法僅在單一平台和 Python 版本上驗證完整覆蓋率。 為此,在
tool.coverage.coverage_conditional_plugin.rules 的 pyproject.toml
區段中定義了數個條件性覆蓋率規則(例如,可使用 no-cover-if-is-windows 標記在 Windows
上執行測試套件時不會被執行的程式碼區塊)。這些規則用於識別僅在特定平台或 Python 版本上被覆蓋的程式碼區段。
值得注意的是,不同 Python 版本之間的覆蓋率報告可能會有些許差異。例如,若使用某個版本的 Python 產生覆蓋率檔案,卻在另一個版本上進行報告,報告中可能會出現因分支遺漏而產生的誤報。因此,進行覆蓋率報告時,應始終採用產生覆蓋率檔案時所使用的最舊版本 Python。
理解承保結果¶
在覆蓋率測試輸出的結尾處,應包含一份關於所收集覆蓋率數據的報告:
名稱 報表 缺失分支 分支比例 覆蓋率 缺失
---------------------------------------------------
總計 7540 0 1040 0 100.0%
這告訴我們,測試套件已經執行了程式碼中所有可能的分支路徑。這雖不能百分之百保證沒有錯誤,但確實意味著我們已經測試了程式碼庫中的每一行程式碼。
如果您對程式碼庫進行修改,可能會導致此覆蓋率出現缺口。一旦發生這種情況,覆蓋率報告會告訴您哪些程式碼行未被執行。例如,假設我們對
some/interesting_file.py 進行了修改,新增了一些邏輯。覆蓋率報告可能會顯示如下內容:
名稱 陳述式 缺失 分支 分支部分 覆蓋率 缺失
-------------------------------------------------------------------------------
src/some/interesting_file.py 111 1 26 0 98.1% 170, 302-307, 320->335
-------------------------------------------------------------------------------
總計 7540 1 1726 0 99.9%
這表示第 170 行、第 302 至 307 行,以及從第 320 行跳轉至第 335 行的分支,均未被測試套件執行。您需要新增測試(或修改現有測試)以恢復此處的程式碼覆蓋率。
主機平台與 Python 版本的覆蓋率報告¶
您可以針對您的平台和 Python 版本產生覆蓋率報告。例如,若要執行測試套件並針對 Python 3.10 產生覆蓋率報告,請執行:
(.venv) $ tox -m test310
(.venv) $ tox -m test310
(.venv) C:\...>tox -m test310
主機平台覆蓋報告¶
如果 tox 可用於所有受支援的 Python 版本,則可透過執行以下指令來報告主機平台的覆蓋率:
(.venv) $ tox p -m test-platform
(.venv) $ tox p -m test-platform
(.venv) C:\...>tox p -m test-platform
HTML 中的報導範圍¶
只要在任何覆蓋率 -html 環境名稱後面加上 tox,即可產生 HTML 覆蓋率報告,例如:
(.venv) $ tox -e coverage-platform-html
(.venv) $ tox -e coverage-platform-html
(.venv) C:\...>tox -e coverage-platform-html
這不只是關於撰寫測試!¶
雖然我們確保會測試所有程式碼,但這項任務並非僅僅在於維持這樣的測試水準。任務的一部分在於邊開發邊審查程式碼。你可以為一件「混凝土製救生衣」編寫一套完整的測試用例……但那件「混凝土製救生衣」對於其原本的用途來說,依然毫無用處!
在開發測試時,您也應確認核心模組在內部是否一致。 若您發現任何方法名稱在內部不一致(例如,某個模組中名為 on_select,但在另一個模組中卻稱為
on_selected),或是資料處理方式不一致,請標記該問題並透過建立工單向我們通報。或者,如果您確信知道該如何處理,請建立拉取請求來修正您發現的問題。
當您確保所有功能運作正常後,即可提交拉取請求以提交您的變更。