【Python单元测试】pytest框架单元测试 配置 命令行操作 测试报告 覆盖率
常用用例
本文重点介绍使用的Mock写法, pytest的基本用法,非本文重点。
pytest 相较于unittest, 写法更加简便。对测试用例直接assert是否符合预期即可
# 定义mock对象, 测试函数形参中需要接收
@patch("")
@patch.object()
# mock对象返回值设置
return_value # 用于Mock返回值
side_effect # 可用于Mock异常情形
# mock对象的校验方式
.assert_called()
.assert_called_with()
.assert_called_once()
.assert_called_once_with()
.assert_not_called()
初始化数据
可以使用测试套 @pytest.fixture
或者 unittest.TestCase
中的 setUp
, setUpClass
初始化数据。
写法一
import pytest
@pytest.fixture # 测试套可以声明在conftest.py / 测试脚本开头 / 测试类中
def init_data():
data = {
"key1": "value1",
"key2": "value2",
}
return data
# 测试套fixture中声明的函数,可以放在conftest.py 或者本单元测试文件中,不需要导入, 直接作为形参接收就可以使用
def test_xx(init_data):
assert init_data.get("key1") == "value1"
写法二
import unittest
class TestXx(unittest.TestCase):
def setUp(self):
self.init_data = { # 测试数据在本测试类中使用
"key1": "value1",
"key2": "value2",
}
睡眠Mock time.sleep
python内置类的mock可以参照此种写法, Mock后内置类/方法实际并不会执行,assert是否被调用
from unittest.mock import patch
def xx():
print("a" * 10)
time.sleep(1) # 此处有睡眠
print("b" * 10)
@patch("time.sleep") # mock后, UT执行时不睡眠
def test_xx(mock_sleep):
xx()
assert mock_sleep.assert_called_once_with(1) # 查看睡眠行是否调用, 并且mock睡眠时间是不是1秒
调用类Mock
# module_a/a.py
class ClassA:
@staticmethod
def cal_sum(a: int, b: int) -> int:
return a + b
def cal_2_num_sum(a, b):
ret = ClassA.cal_sum(a, b)
return ret
# unit_test/test_module_a.py
from unittest.mock import patch
from module_a.a import cal_2_num_sum
@patch("module_a.ClassA")
def cal_2_num_sum(mock_class_a):
mock_class_a.return_value.cal_sum.return_value = 0
ret = cal_2_num_sum(1, 2)
assert ret == 0
@patch.object(ClassA, "cal_sum")
def cal_2_num_sum(mock_cal_sum):
mock_cal_sum.return_value = 0
ret = cal_2_num_sum(1, 2)
assert ret == 0