測試時間¶
大多數軟體開發並不涉及編寫新程式碼,而是修改現有程式碼。確保現有程式碼繼續按照我們期望的方式運作是軟體開發過程的關鍵部分。確保我們的應用程式行為的一種方法是使用 測試套件 。
運行測試套件¶
事實上,我們的專案已經有測試套件了!當我們最初產生專案時,產生了兩個資料夾: src 和 tests 。 src 資料夾包含我們應用程式的程式碼;
tests 資料夾包含我們的測試套件。在 tests 資料夾內有一個名為 test_app.py 的文件,其中包含以下內容:
def test_first():
"""應用程式的初步測試"""
assert 1 + 1 == 2
這是一個 Pytest 的 測試範例 - 可以執行以驗證應用程式的某些行為的程式碼區塊。在本例中,測試僅是一個範例,不會測試有關我們應用程式的任何內容 - 但它是我們可以執行的測試。
我們可以使用 briefcase dev 的 --test 選項來執行這個測試套件。由於這是我們第一次執行測試,我們還需要傳入 -r
選項以確保測試要求也已安裝:
(beeware-venv) $ briefcase dev --test -r
[helloworld] 安裝所需套件...
...
安裝開發環境所需套件... 完成
[helloworld] 在開發環境中執行測試套件...
===========================================================================
============================= 測試會話開始 ==============================
平台 darwin -- Python 3.11.0, pytest-7.2.0, pluggy-1.0.0 -- /Users/brutus/beeware-tutorial/beeware-venv/bin/python3.11
快取目錄:/var/folders/b_/khqk71xd45d049kxc_59ltp80000gn/T/.pytest_cache
根目錄:/Users/brutus
外掛程式:anyio-3.6.2
正在收集... 已收集 1 項
tests/test_app.py::test_first 通過 [100%]
============================== 1 項通過,耗時 0.01 秒 ===============================
(beeware-venv) $ briefcase dev --test -r
[helloworld] 安裝所需套件...
...
正在安裝開發環境所需套件... 完成
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試會話開始 ==============================
平台 linux -- Python 3.11.0
pytest==7.2.0
py==1.11.0
pluggy==1.0.0
快取目錄: /tmp/.pytest_cache
根目錄: /home/brutus
外掛程式: anyio-3.6.2
正在收集... 已收集 1 項
tests/test_app.py::test_first 通過 [100%]
============================== 1 項通過,耗時 0.01 秒 ===============================
(beeware-venv) C:\...>briefcase dev --test -r
[helloworld] 安裝所需套件...
...
安裝開發環境所需套件... 完成
[helloworld] 在開發環境中執行測試套件...
===========================================================================
============================= 測試會話開始 ==============================
平台 win32 -- Python 3.11.0
pytest==7.2.0
py==1.11.0
pluggy==1.0.0
快取目錄: C:\Users\brutus\AppData\Local\Temp\.pytest_cache
根目錄: C:\Users\brutus
外掛程式: anyio-3.6.2
正在收集 ... 已收集 1 項
tests/test_app.py::test_first 通過 [100%]
============================== 1 項通過,耗時 0.01 秒 ===============================
成功了!我們剛剛執行了一個測試,證實了 Python 的數學按照我們期望的方式工作(真是鬆了一口氣!)。
讓我們用一個測試來取代這個範例,以驗證我們的 greeting() 方法的行為是否符合我們的預期。將 test_app.py 的內容替換為以下內容:
from helloworld.app import greeting
def test_name():
"""若提供名稱,問候語中將包含該名稱"""
assert greeting("Alice") == "Hello, Alice"
def test_empty():
"""若未提供姓名,則顯示通用問候語"""
assert greeting("") == "Hello, stranger"
這定義了兩個新的測試,驗證我們期望看到的兩個行為:提供名稱時的輸出,以及名稱為空時的輸出。
我們現在可以重新運行測試套件。這次,我們不需要提供 -r 選項,因為測試要求已經安裝了;我們只需要使用 --test 選項:
(beeware-venv) $ briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
正在收集... 已收集 2 項
tests/test_app.py::test_name 通過 [ 50%]
tests/test_app.py::test_empty 通過 [100%]
============================== 2 項通過,耗時 0.11 秒 ===============================
(beeware-venv) $ briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
正在收集... 已收集 2 項
tests/test_app.py::test_name 通過 [ 50%]
tests/test_app.py::test_empty 通過 [100%]
============================== 2 項通過,耗時 0.11 秒 ===============================
(beeware-venv) C:\...>briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
正在收集... 已收集 2 項
tests/test_app.py::test_name 通過 [ 50%]
tests/test_app.py::test_empty 通過 [100%]
============================== 2 項通過,耗時 0.11 秒 ===============================
非常好!我們的 greeting() 實用方法按預期工作。
用測試來驅動開發¶
現在我們有了測試套件,我們可以用它來驅動新功能的開發。讓我們修改我們的應用程序,為某個特定用戶提供特殊的問候語。我們可以先為我們希望在
test_app.py 底部看到的新行為新增一個測試案例:
def test_brutus():
"""若名字是 Brutus,則會顯示特別的問候語"""
assert greeting("Brutus") == "當心 Python 的 IDE!"
然後,使用這個新測試來執行測試套件:
(beeware-venv) $ briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
收集中 ... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 失敗 [100%]
=================================== 失敗項目 ===================================
_________________________________ test_brutus __________________________________
def test_brutus():
"""若名稱是 Brutus,則提供特別的問候語"""
> assert greeting("Brutus") == "BeeWare the IDEs of Python!"
E AssertionError: assert 'Hello, Brutus' == 'BeeWare the IDEs of Python!'
E - BeeWare the IDEs of Python!
E + Hello, Brutus
tests/test_app.py:19: AssertionError
=========================== 簡短測試摘要資訊 ============================
失敗 tests/test_app.py::test_brutus - AssertionError: assert 'Hello, Brutus...
========================= 1 項失敗,2 項通過,耗時 0.14 秒 ==========================
(beeware-venv) $ briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試會話開始 ==============================
...
正在收集... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 失敗 [100%]
=================================== 失敗項目 ===================================
_________________________________ test_brutus __________________________________
def test_brutus():
"""若名字是 Brutus,則提供特別的問候語"""
> assert greeting("Brutus") == "BeeWare the IDEs of Python!"
E AssertionError: assert 'Hello, Brutus' == 'BeeWare the IDEs of Python!'
E - BeeWare the IDEs of Python!
E + Hello, Brutus
tests/test_app.py:19: AssertionError
=========================== 簡短測試摘要資訊 ============================
測試失敗:tests/test_app.py::test_brutus - AssertionError: assert 'Hello, Brutus...
========================= 1 項失敗,2 項通過,耗時 0.14 秒 ==========================
============================== 2 項通過,耗時 0.11 秒 ===============================
(beeware-venv) C:\...>briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試會話開始 ==============================
...
正在收集 ... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 失敗 [100%]
=================================== 失敗項目 ===================================
_________________________________ test_brutus __________________________________
def test_brutus():
"""若名稱是 Brutus,則提供特別的問候語"""
> assert greeting("Brutus") == "BeeWare the IDEs of Python!"
E AssertionError: assert 'Hello, Brutus' == 'BeeWare the IDEs of Python!'
E - BeeWare the IDEs of Python!
E + Hello, Brutus
tests/test_app.py:19: AssertionError
=========================== 簡短測試摘要資訊 ============================
失敗 tests/test_app.py::test_brutus - AssertionError: assert 'Hello, Brutus...
========================= 1 項失敗,2 項通過,耗時 0.14 秒 ==========================
這次,我們看到測試失敗 - 輸出解釋了失敗的根源:測試期望輸出 BeeWare the IDEs of Python! ,但我們的 greeting()
實現返回 Hello, Brutus 。讓我們修改 src/helloworld/app.py 中的 greeting() 實作以獲得新的行為:
def greeting(name):
if name:
if name == "Brutus":
return "小心 Python 的 IDE!"
else:
return f"你好,{name}"
else:
return "你好,陌生人"
如果我們再次運行測試,我們現在將看到測試通過:
(beeware-venv) $ briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
收集中 ... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 通過 [100%]
============================== 3 項測試通過,耗時 0.15 秒 ===============================
(beeware-venv) $ briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
收集中 ... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 通過 [100%]
============================== 3 項測試通過,耗時 0.15 秒 ===============================
(beeware-venv) C:\...>briefcase dev --test
[helloworld] 正在開發環境中執行測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
正在收集 ... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 通過 [100%]
============================== 3 項測試通過,耗時 0.15 秒 ===============================
運行時測試¶
到目前為止,我們一直在開發模式下執行測試。當您開發新功能時,這特別有用,因為您可以快速迭代添加測試,並添加程式碼以使這些測試通過。但是,在某些時候,您需要驗證您的程式碼在部署的環境中是否也可以正確運行。
--test 和 -r 選項也可以傳遞給 run 指令。如果您使用 briefcase run --test -r
,將運行相同的測試套件,但它將在部署的環境中運行,而不是在您的開發環境中運行:
(beeware-venv) $ briefcase run --test -r
[helloworld] 更新應用程式程式碼...
安裝 src/helloworld... 完成
安裝測試... 完成
[helloworld] 更新需求...
...
[helloworld] 已建立 build/helloworld/macos/app/Hello World.app (測試模式)
[helloworld] 啟動測試套件...
===========================================================================
設定隔離的 Python...
預先初始化 Python 執行環境...
PythonHome: /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
PYTHONPATH:
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python311.zip
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib/lib-dynload
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app_packages
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app
設定 argc/argv...
初始化 Python 執行環境...
安裝 Python NSLog 處理程序...
執行應用程式模組:tests.helloworld
---------------------------------------------------------------------------
============================= 測試階段開始 ==============================
...
收集中... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 通過 [100%]
============================== 3 項測試通過,耗時 0.21 秒 ===============================
[helloworld] 測試套件通過!
(beeware-venv) $ briefcase run --test -r
[helloworld] 完成應用程式設定...
目標平台:ubuntu:jammy (Vendor base debian)
偵測 glibc 版本... 完成
目標 glibc 2.35
目標 Python 3.10
[helloworld] 更新應用程式程式碼...
安裝 src/helloworld... 完成
安裝測試模組... 完成
[helloworld] 更新套件需求...
...
[helloworld] 已建置 build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/bin/helloworld (測試模式)
[helloworld] 啟動測試套件...
===========================================================================
============================= 測試階段開始 ==============================
...
收集中... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 通過 [100%]
============================== 3 項通過,耗時 0.21 秒 ===============================
(beeware-venv) C:\...>briefcase run --test -r
[helloworld] 更新應用程式程式碼...
安裝 src/helloworld... 完成
安裝測試... 完成
[helloworld] 更新需求...
...
[helloworld] 已建立 build\helloworld\windows\app\src\Hello World.exe (測試模式)
===========================================================================
日誌開始時間:2022-12-02 10:57:34Z
預初始化 Python 執行環境...
PythonHome:C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
PYTHONPATH:
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\python311.zip
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app_packages
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app
設定 argc/argv...
初始化 Python 執行環境...
執行 app 模組:tests.helloworld
---------------------------------------------------------------------------
============================= 測試會話開始 ==============================
...
收集中... 已收集 3 項
tests/test_app.py::test_name 通過 [ 33%]
tests/test_app.py::test_empty 通過 [ 66%]
tests/test_app.py::test_brutus 通過 [100%]
============================== 3 項測試通過,耗時 0.21 秒 ===============================
與 briefcase dev --test 一樣,僅在第一次執行測試套件時才需要 -r 選項,以確保測試依賴項存在。在後續運行中,您可以忽略此選項。
您還可以在移動環境下使用 --test 選項: - 因此 briefcase run iOS --test 和 briefcase run
android --test 都可以工作,在您選擇的移動設備上運行測試套件。