1. Pytest简介
Pytest是一个Python的单元测试框架,它可以扩展python的unittest,并允许使用丰富的插件和外部库进行测试。Pytest的主要优点是易于上手,测试用例编写简洁,输出结果易于阅读,还有丰富的插件支持。
Pytest的主要特点如下:
支持参数化测试
支持fixture(模拟一个对象或者实例)
支持collect模式(自动查找测试用例)
支持多线程并发执行测试用例
支持插件体系,可以自定义插件扩展功能
支持断言失败时打印失败的数据
最大化的输出结果,通过丰富的输出格式性能测试等更高级别测试
2. Pytest的安装
安装pytest只需要在终端输入以下命令就可安装:
pip install pytest
3. 测试用例编写
3.1 断言
在编写测试用例时,需要编写断言(assert),其作用是验证代码是否正常运行。
Pytest中有多种断言方式,常见的一些如下:
assert
assert expression
assert expression1 == expression2
assert expression1 in expression2
assert response.json()['code'] == 400
3.2 参数化测试
参数化测试可以很方便的测试同类函数或方法对不同参数的返回结果。Pytest提供了一个很好的解决方案,以确保我们的测试可以覆盖各种情况。
pytest.mark.parametrize装饰器的典型用法如下:
import pytest
@pytest.mark.parametrize("test_input,expected",[("3+5",8),("2+4",6),("6*9",42)])
def test_eval(test_input, expected):
assert eval(test_input) == expected
3.3 对象模拟和拦截
测试中,对于有依赖的函数或模块,我们可以使用fixture先行执行,并生成不同的实例或对象。
一个简单的使用fixture的例子如下:
import pytest
@pytest.fixture
def obj():
return MyClass()
def test_obj(obj):
assert obj.prop == 'hello'
除了fixture,我们还可以使用mock拦截某一个函数的调用,将返回值设置为我们期望的值。
import pytest
from unittest.mock import patch
def test_mock():
with patch.object(MyClass, "method", return_value=42) as mock_method:
obj = MyClass()
assert obj.method() == 42
4. Pytest测试用例执行
Pytest执行测试用例的命令如下:
pytest test_sample.py
比如上面的命令将运行test_sample.py文件中的所有测试用例。
在执行pytest时,你还可以添加不同的参数,比如:
–verbose
详细信息
–quiet
安静模式
–tb=short
只显示前两个traceback信息
5. 测试覆盖率
测试覆盖率是一种很好的衡量测试质量的方法,它可以帮助我们发现未被测试到的逻辑或者代码。
Pytest-cov便是一个很好的测试覆盖率插件,使用命令行参数即可开启:
pytest --cov-report term --cov-report html --cov=my_app tests/
这将生成一个HTML报告,并在终端中显示覆盖率详细信息。其中,–cov-report term
用来显示终端报告,–cov-report html
用来生成HTML报告,–cov
用于对指定的源代码进行覆盖评估。
总结
Pytest是一个易于上手,功能丰富的Python单元测试框架,在Python开发中有很广泛的应用,尤其适合小项目和代码库的测试。在编写测试用例时,需要用到断言(assert)、参数化测试、fixture、mock拦截等功能,可以大大地增加测试用例的复用性,提升工作效率。通过使用pytest-cov插件,我们可以很方便的检测测试覆盖率,发现未被测试到的逻辑或者代码,提升测试质量。