网站首页 文章专栏 python 代码测试
python 代码测试
创建于:2021-07-04 08:21:20 更新于:2025-05-23 17:58:41 羽瀚尘 601

代码测试

pytest生成html报告

## 生成html格式的报告
## 需预先装上pytest-html
pip install pytest_html
pytest -v test_1.py --html=test.html

pytest 覆盖率测试与报告

安装pytest-cov

pip3 installl pytest-cov

在pytest中调用coverage
其中的点表示在当前目录中统计覆盖率

pytest --cov=. 

运行过后当前的目录会出现.coverage文件

生成html报告

coverage html

会在当前目录中生成htmlcov文件夹,打开里面的index.html可以查看覆盖率报告

主页面,显示统计信息
coverage主页面

模块页面,给出测试的代码与未测试的代码
单个模块页面

mock

{'_mock_return_value': True, '_mock_parent': None, '_mock_name': 'write', '_mock_new_name': '', '_mock_new_parent': None, '_spec_class': None, '_spec_set': None, '_spec_signature': None, '_mock_methods': None, '_mock_children': {}, '_mock_wraps': None, '_mock_delegate': None, '_mock_called': True, '_mock_call_args': call(b'UU\x08\x03\x01\xe8\x03\x01\xd0\x07'), '_mock_call_count': 1, '_mock_call_args_list': [call(b'UU\x08\x03\x01\xe8\x03\x01\xd0\x07')], '_mock_mock_calls': [call(b'UU\x08\x03\x01\xe8\x03\x01\xd0\x07')], 'method_calls': [], '_mock_unsafe': False, '_mock_side_effect': None}

测试mock要注意的事项

下面的代码中将整个serial.Serial都mock了,所以后续的serial.Serial.read mock就不起作用了。

两个方案,一个是自定义一个class,初始化后从serial.Serial mock返回;另一个是只mock
serial.Serial.__init__.

  • 方案1 对整个模块进行模拟,然后返回自己定义的一个class。
def test_voltage(mocker):
    '''测试获取舵机控制板的电压
    '''

    voltage_bin = struct.pack('<HBBH',*(0x5555, 0x04, 0x0F, 7500))
    class mock_serial:
        def read(self, param):
            return voltage_bin
    
    Serial = mocker.patch('serial.Serial', return_value=mock_serial)
    write = mocker.patch('src.data_trans.virtual_dev.write', return_value=1)
    read = mocker.patch('serial.Serial.read', return_value=voltage_bin)
    req_dict = {
        'ActionType': 'get_voltage',
        'ActionDev':{
            'type': 'com',
            'path': '/dev/ttyACM0',
            'rate': 9600
        }
    }
    api_ins = api(req_dict)
    ret_dict = api_ins.process()
    assert 1 == Serial.call_count
    assert 1 == write.call_count
    assert 7500 == ret_dict['Result']
  • 方案2 只对__init__方法进行模拟。
def test_voltage(mocker):
    '''测试获取舵机控制板的电压
    '''

    voltage_bin = struct.pack('<HBBH',*(0x5555, 0x04, 0x0F, 7500))

    Serial = mocker.patch('serial.Serial.__init__', return_value=None)
    write = mocker.patch('src.data_trans.virtual_dev.write', return_value=1)
    read = mocker.patch('serial.Serial.read', return_value=voltage_bin)
    req_dict = {
        'ActionType': 'get_voltage',
        'ActionDev':{
            'type': 'com',
            'path': '/dev/ttyACM0',
            'rate': 9600
        }
    }
    api_ins = api(req_dict)
    ret_dict = api_ins.process()
    assert 1 == Serial.call_count
    assert 1 == write.call_count
    assert 7500 == ret_dict['Result']