测试时间¶
大多数软件开发并不涉及编写新代码,而是修改现有代码。确保现有代码以我们期望的方式继续正常工作是软件开发过程的关键部分。确保应用程序行为的方法之一是使用一个\ 测试套件。
运行测试套件¶
原来我们的项目已经有了一个测试套件!我们最初生成项目时,会生成两个顶级目录:[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(基于 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`` 都可以在你选择的移动设备上运行测试套件。