介绍了 Python 中各种测试方法与场景。
Test runner
一个特别设计的应用,用来跑测试,检查输出,调试和诊断你的代码。
Python 有几种测试工具:
- unittest
- nose or nose2
- pytest
unittest
unittest 要求:
- 把你的测试代码写进 class 或者方法
- 在 unittest.TestClass 类中使用一系列特殊断言
一个简单的测试例子:
1 | import unittest |
nose
nose 兼容其他测试框架写的代码,nose 会在你的目录寻找所有 py
文件和测试用例进行测试。
1 | $ pip install nose2 |
pytest
也支持 unitters,它的测试用例是以 test_
开头的一些函数。 pytest 的优点是:
- 支持内置的
assert
命令 - 可以 filter 测试用例
- 支持从上次失败的测试重新开始
- 生态系统丰富,支持很多插件
一个 pytest 的测试代码:
1 | def test_sum(): |
编写测试
一个简单的测试项目:
1 | project/ |
1 | # __init__.py |
断言是你的测试条件,比如你预期,可以通过 .assert*()
编写你的断言,比如 .assertEqual(a, b)
,它和 a==b
其实是相等的。
类似的函数还有:
- assertTrue(x)
- assertFalse(x)
- assertIs(a, b)
执行测试
一般通过执行 test.py
文件来测试,在这个文件中你会调用 unittest.main()
函数。
或者也可以通过命令行的 python -m unittest test
来执行测试。
通过 python -m unittest -v test
来执行测试并输出每一个测试的内容。
通过 python -m unittest discover
让其自动发现目前目录戏的 test*.py
文件进行测试,此命名还支持子包的路径: python -m unittest discover -s tests -t src
, 其中 src 是子目录名。
在 PyCharm 中,你可以执行 Run 'Unittests in ..' 来执行测试,在 VS Code 中,进入命令模式,输入 test 即可以看到相关指令。
Web 框架测试
Django, Flask
这类测试很不一样,因为它们内置了一些诸如路由、视图、模型等必要的模块,在启动的时候需要导入,这就好像你要测试一辆车,则需要先将电脑准备好。
但这类框架也提供了测试工具,比如 Django 在你执行 startapp
的时候,会自动创建 test.py
文件。
如果你的 Django 项目中没有的话,也可以自己创建,与前面的例子不一样的是,你需要将你的测试类继承自 django.test.TestCase
,而不是 unittest.TestCase
.
1 | from django.test import TestCase |
在执行的时候,也需要换成 python manage.py test
.
如果你有多个测试文件,则创建一个 test 文件夹,将你的测试文件名更改为 test_*.py,django 会自动发现并执行这些测试。
更多 Django 测试的内容可以参考这里
对于 Flask 则又有一些不同,需要设置应用的模式为 test, 然后你可以是实例化一个测试客户端,根据路由去做一些测试。
实例化的配置都在 setup 方法中,参考下面的例子:
1 | import my_app |
配置好后,可以直接使用 -m unittest discover
进行测试。
更多 Flask 测试的内容可以参考 Flask Documentation Website
高级测试场景
基本的测试步骤:
- 创建你的输入
- 执行代码,捕捉输出
- 对比输出和预期的结果
这里输入又叫 fixture, 一般创建后可以重复使用。
如果你跑一个测试多次,但使用不同的参数,并预期结果是一样的,这叫 parameterization。
集成测试
集成测试,顾名思义,会集成多个测试用来检查其每个模块是否都工作,它会站在用户的角度去测试你的软件。
通常集成测试的代码会和单元测试的分开,因为集成测试需要跑更多的模块:
1 | project/ |
使用 unitters, 你可以通过 -s 来指定只包含某个部分的代码来进行测试。
python -m unittest discover -s tests/integration
如果你的测试依赖一些文件,可以新建fixtures文件夹,将数据放到里面。
环境测试
你想知道你的代码放在不同版本的 python 中是否工作,可以使用 Tox.
Tox 使用需要配置,它有一个配置文件,里面包括:
- 测试需要执行的代码
- 执行测试需要的包
- 目标环境版本
你可以执行 tox-quickstart
来启动快速配置脚本,回答问题即可生成 tox.ini
配置文件。
自动测试
自动化测试工具,又被称为 CI/CD 工具,意思是 持续集成持续部署(Continuous Integration/Continuous Deployment)。
Travis CI 是在 Python 下不错的 CI 工具,并且对于所有 Github,GitLab 上开源的项目都免费,它会创建一个 .travis.yml
配置文件:
1 | language: python |
这个配置会测试代码在 python 2.7, 3.7 中是否工作,安装你配置文件中的包,并执行所有自动发现的单元测试。
当你配置好之后,Travis CI 会在你每次 push 后自动测试你的代码。
其他测试相关内容
- 使用 Linters, 比如 flake8
- 保持干净的测试代码,遵循 DRY( Don’t Repeat Yourself) 原则
- 使用 timeit 或是 pytest-benchmark 模块,查看测试性能
- 使用 bandit 测试你的包的安全问题.