跳轉到

編寫、執行與測試程式碼

要修復錯誤或實作新功能,您將需要撰寫一些新程式碼。

開始編寫程式碼前,請確保已建立開發環境,並在分支上進行開發

我們有一份 程式碼風格指南,其中概述了為 BeeWare 編寫程式碼的準則。

測試驅動開發

確保程式碼能如預期運作的好方法,是先撰寫一個測試案例來驗證它。這個測試案例最初應該會失敗,因為它所測試的程式碼尚未存在。接著,您可以撰寫必要的程式碼變更以讓測試通過,並確信您所寫的程式碼確實解決了您預期要解決的問題。

執行您的程式碼

寫完程式碼後,您需要確保它能夠執行。您必須手動執行程式碼,以驗證其運作結果是否符合預期。若尚未進行,建議您為所做的變更撰寫測試案例;如前所述,若程式碼被註解掉或不存在,此測試應會失敗。

您將把測試案例新增至測試套件中,以便它能與其他測試一併執行。下一步是執行該測試套件。

執行測試 及覆蓋率

BeeWare 使用 tox 來管理測試流程,並使用 pytest 來管理其自身的測試套件。

預設的 tox 指令包含執行:

  • 預提交鉤子
  • towncrier 版本說明檢查
  • 文件檢查

  • 適用於各 Python 版本的測試套件

  • 程式碼覆蓋率報告

這基本上就是您提交拉取請求時,CI 所執行的流程。

若要執行完整的測試套件,請執行:

(.venv) $ tox
(.venv) $ tox
(.venv) C:\...>tox

執行完整的測試套件可能需要一段時間。您可以透過並行執行 tox,或執行 tox p(或 tox run-parallel)來大幅加快速度。當您並行執行測試套件時,在執行過程中獲得的進度回報會較少,但測試執行結束後仍會收到任何發現問題的摘要。您應該會看到一些輸出訊息,顯示測試已執行。 您可能會看到 SKIPPED 個測試,但絕不應收到任何 FAILERROR 的測試結果。我們會在合併每個修補程式之前執行完整的測試套件。若該過程發現任何問題,我們便不會合併該修補程式。如果您確實發現測試錯誤或失敗,那可能是您的測試環境有異常,或是您發現了我們尚未遇過的邊界案例——無論是哪種情況,請務必告知我們!

除了測試通過之外,這應該會顯示 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.rulespyproject.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),或是資料處理方式不一致,請標記該問題並透過建立工單向我們通報。或者,如果您確信知道該如何處理,請建立拉取請求來修正您發現的問題。

當您確保所有功能運作正常後,即可提交拉取請求以提交您的變更。