pytest的学习记录

1. pytest.ini

pytest的主配置文件,可以改变pytest的默认行为
不能使用中文、空格、引号、冒号

addopts配置:配置命令行参数

-vs:打印详细调试信息
-n:支持多线程或分布式运行(pytest-xdist插件)
-html:生成html测试报告(pytest-html插件)
-x:出现失败则停止执行
-k:模糊匹配
-maxfail:出现几条失败则停止执行

注册mark标记

markers = 
    demo:explain
xfail_strict = True

@pytest.mark.xfail()

制定pytest最低版本

minversion = 5.0

testpaths配置

python_files =     test_*  *_test  test*
python_classes =   Test*   test*
python_functions = test_*  test*

log_cli配置

控制台实时输出日志
log_cli=True 或False,log_cli=1 或 0
加了log_cli=1,可以清晰看到哪个package下的哪个module下的哪个测试用例是否passed还是failed,批跑不建议添加

norecursedirs配置

收集测试用例一般会遍历testpaths,可用norecursedirs简化

2. conftest.py

  1. 测试用例的一些fixture配置,不需要import即可实现数据共享
  2. 可结合fixtures使用
  3. conftest.py与用例在一个包下,并需要有_init_.py文件
  4. 一个项目可以有多个conftest.py
    场景:每个用例的setup和teardown,token,测试数据,配置信息,数据库连接等
import pytest
import pymysql

@pytest.fixture
def db_connection():
    db = pymysql.connect(
    host='10.70.32.12',
    port=3306,
    user='root',
    password='Aa123456!',
    db='iap'
    )
    yield db
    db.close()

3. init.py

  1. python检测到目录下存在_init_.py,就会把这个目录当成一个module
  2. init.py可以是一个空文件
  3. 可在_init_.py中对核心子模块重新命名,引用的时候就可以from module import * 调用所有该模块下方法

4. 夹具fixtures

@pytest.fixture
def test_test():
    pass
- scope:有四个级别参数"function"(默认),"class""module""session"
-function:每一个函数或方法都会调用
-class:每一个类调用一次,一个类中可以有多个方法
-module:每一个.py文件调用一次,该文件内又有多个function和class
-session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
def test_db_query(db_connection):
    pass

5. 覆盖率pytest_cov

安装pytest_cov,执行pytest --cov=myproject,运行并提供myproject的覆盖率报告

6. @pytest.mark.parametrize

输入数据集

def readsql():
    # 读取SQL数据
    with open('AT_RT_data/getinfo.sql', 'r', encoding='utf-8') as f:
        sql_list = f.readlines()
        return sql_list
@pytest.mark.parametrize('sql', readsql())

@pytest.mark.parametrize(
    'input_value,expected_output', 
    [(4,8),(3,6),(2,4),(1,2)]
)

7. pytest_generate_tests

允许动态的生产测试数据,适用于复杂的逻辑或者外部数据

import pytest


def pytest_generate_tests(metafunc):
    if "input_value" in metafunc.fixturenames:
        metafunc.parametrize('input_value,expected_output',
                             [(4, 8), (3, 6), (2, 4), (1, 2)])


def test_compute(input_value, expected_output):
    assert input_value * 2 == expected_output

8. 钩子函数Hooks和插件Plugins

9. Pytest-xdist 并行测试

执行命令使用pytest -n 6 #跨4个cpu甚至不同机器执行
#并发不等于并行
在这里插入图片描述

10. Pytest-asyncio 并发异步测试

https://liaoxuefeng.com/books/python/async-io/asyncio/

async def hello(name):
    print("hello %s! (%s)" % (name, threading.current_thread()))
    # 通过await调用另一个async函数,由async内不消息循环调用
    await asyncio.sleep(1)
    print("hello %s again! (%s)" % (name, threading.current_thread()))
    return name


async def main():
    # 通过asyncio.gather()并发执行若干个async函数
    L = await asyncio.gather(hello("Bob"), hello("Alice"))
    print(L)
    # 使用asyncio.run()调度一个协程
asyncio.run(main())

11. 测量执行时间

@pytest.mark.timing
def test_execution_time():
    start_time = time.time()
    elapsed_time = time.time() - start_time
    assert elapsed_time < 2

12.基准性能测试

python自带timeit
在这里插入图片描述

pyperf
在这里插入图片描述

pytest-benchmark
在这里插入图片描述

运行pytest --benchmark-save=benchmark_data,保存基准测试结果,以便后续进行比较
运行pytest --benchmark-histogram 直接图表展示结果

  1. name: 测试函数的名称。每个测试函数都有自己的名称,用于区分不同的测试。
  2. min: 执行测试函数的最小时间。这是在所有运行中观察到的最短时间。
  3. max: 执行测试函数的最大时间。这是在所有运行中观察到的最长时间。
  4. mean: 执行测试函数的平均时间。这是所有运行时间的平均值。
  5. stddev: 执行测试函数的标准差。标准差用于衡量运行时间的离散程度。较小的标准差表示运行时间更稳定。
  6. median: 执行测试函数的中位数时间。中位数是将所有运行时间按大小排序后,位于中间位置的值。
  7. IQR: 四分位距(InterQuartile Range)。这是一种不同的测量方差的方法。
  8. outliers: 执行测试函数时观察到的异常值数量。异常值是指与其他观测值相比明显偏离的值。
  9. OPS: 表示在一定时间内(比如1秒)测试方法被调用了多少次。
  10. rounds: 执行测试函数的运行次数。pytest-benchmark默认会多次运行测试函数,并根据这些运行结果计算出平均时间等统计数据。
  11. iterations: 每个运行中执行测试函数的迭代次数。pytest-benchmark会在每个运行中多次迭代执行测试函数,并计算每次迭代的时间。

13.模拟外部服务或者API

https://www.cnblogs.com/goldsunshine/p/15265187.html

13.1 unittest.mock

import requests
from unittest.mock import MagicMock


def test_external_api():
    requests.get = MagicMock(
        return_value=MagicMock(
            status_code=200,
            json=lambda: {"key": "value"}
        )
    )
    requests.get.assert_called_with('https://api.external-service.com/endpoint')

13.2 pytest-mock

提供比unittest.mock更简单、强大的功能
需要进行pip安装,pip install pytest-mock

def test_fucntion(mocker):
    mock = mocker.patch('some_function.external_function', return_value=42)
    result = function_to_test()
    assert result == 42
    mock.assert_called_once()

在上述例子中,使用mocker.patch将some_function.external_function替换成mock对象

14. pytest持续集成

15. 代码覆盖率

pytest-cov插件

pytest --cov=my_project --cov-report HTML term-missing

–cov=my_project:计算my_project的覆盖率
–cov-report:指定覆盖率报告,html或者xml
term-missing:显示覆盖范围并列出缺少覆盖的线路

16. UI代码覆盖率

启用UI测试覆盖率,在Graddle设置一个属性

android {
    buildTypes{
        testCoverageEnabled = true
    }
}

17. 安全测试建议

  1. 威胁建模:识别潜在安全威胁和漏洞
  2. 安全编码实践:代码审查、代码规范、用户输入的注入攻击
  3. 数据加密:加密协议(HTTPS/TLS),对设备存储的敏感数据加密
  4. 事件响应计划:制定响应安全事件的计划,包括通讯协议和补救步骤,定期演练,更新计划(保证计划有效性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值