美文网首页Pytest教程pythonAutoTest-AutoAI
Pytest自动化实践教程1-Pytest基础使用

Pytest自动化实践教程1-Pytest基础使用

作者: 韩志超 | 来源:发表于2019-03-27 23:33 被阅读60次

    目录

    1-Pytest基础使用
    2-Pytest自动化测试框架实践
    3-Pytest+Allure+Jenkins持续集成

    Pytest基础使用

    Pytest是一个易用强大灵活的功能测试框架,并且兼容unittest和nose的测试用例

    • 易用: 用例编写简单, 断言方便
    • 强大: 全能的mark, 强大的fixtures
    • 灵活: 灵活的执行控制及丰富的插件

    安装

    pip3 install pytest
    

    用例编写及断言

    # filename: test_reg.py
    import requests
    
    def test_user_reg():  # 可以不用写类
        url = "http://47.94.156.36:5000/api/user/reg/"
        data  = {"name": "临渊", "password": "123456"}
        res = requests.post(url, json=data)
        assert '100000' == res.json()['code']  # 断言使用Python原生assert
        assert '注册成功' in res.json()['msg']
    

    运行方法
    在当前文件所在目录,打开命令行,运行:

    pytest test_reg.py
    

    或者在脚本中,导入pytest,使用pytest.main([...])运行:

    ...
    import pytest
    
    def test_user_reg():
        ...
    
    if __name__ == '__main__':
        pytest.main(['test_reg.py'])
    

    全能的mark

    mark主要用来标记用例,通过不同的标记实现不同的运行策略
    主要用途:

    1. 标记和分类用例: @pytest.mark.level1
    2. 标记用例在指定条件下跳过或直接失败 @pytest.mark.skipif()/xfail()/incremental
    3. 标记使用指定fixture(测试准备及清理方法) @pytest.mark.usefixtures()
    4. 参数化 @pytest.mark.parametrize
    5. 标记超时时间 @pytest.mark.timeout(60)
    6. 标记失败重跑次数@pytest.mark.flaky(reruns=5, reruns_delay=1)

    标记和分类用例

    # 标记用例, 支持多个标记, 运行时可以运行带/不带指定标记的用例
    @pytest.mark.apitest
    @pytest.mark.level1
    def test_user_reg():
        ...
    

    标记用例在指定条件下跳过或直接失败

    db = DB()  # 封装的数据对象, 详见之前的文章
    # 如果查询到用户存在则跳过用例, 也可以使用@pytest.mark.xfail()置为失败
    @pytest.mark.skipif(db.check_user("临渊"))  
    def test_user_reg():
        ...
    
    @pytest.mark.incremental  # 如果类中某条没过,之后的全部置为失败
    class TestReg():
        ...
    
    

    标记使用指定fixtures

    db=Db()  # 封装的数据对象, 详见之前的文章
    
    @pytest.fixture()  # 声明为fixture(测试准备/清理)方法
    def del_user():
        db.del_user_if_exist("临渊")  # setup
        yield
        db.del_user_if_exist("临渊")  # teardown
    
    
    @pytest.mark.usefixtures("del_user")
    def test_user_reg():
        ...
    
    

    参数化

    names = ["羡鱼", "abc123", "admin@123.com"]
    
    @pytest.mark.parametrize("name", names)
    def test_user_reg(name): # 接收的变量名要和parametrize的"name"一致
        url = 'http://47.94.156.36:5000/api/user/reg/'
        data  = {"name": name, "password": "123456"}
        res = requests.post(url, json=data)
    
    # 执行时会根据数据的数量执行3条用例
    

    标记超时时间

    pip3 install pytest-timeout

    @pytest.mark.timeout(60)
    def test_user_reg():  # 当前用例限定60s超时
       ...
    

    或命令行使用pytest --timeout=300限定所有用例

    标记失败重跑次数

    pip3 install pytest-rerunfailures

    @pytest.mark.flaky(reruns=5, reruns_delay=1)  # 如果失败则延迟1s后重跑
    def test_user_reg()  # 最多重跑5次, reruns_delay可以不传
        ....
    

    pytest --reruns 5 --reruns-delay 1

    强大的fixtures(测试准备/清理)方法

    Pytest提供会话(一次测试运行为一个会话)/包/模块/类/方法级别以及用例单独的fixtures方法, 并且支持unittest/nose中的setUpModule/tearDownModule,setUpClass/tearDownClass,setUp/tearDown方法,并且使用更加灵活

    unittest/nose中没有会话级的fixtures方法, 同时没有个别用例单独使用的fixtures方法

    fixture参数支持scope(生效范围)和autouse(自动使用)

    生效范围

    • session: 会话级, 所有执行的用例
    • package: 包级, 当前包所有执行的用例
    • module: 模块级
    • class: 类级
    • function: 方法级
    @pytest.fixture(scope="session", autouse=True)  # 声明所有执行的用例自动使用
    def open_browser():
        driver = webdriver.Chrome()
        yield driver
        driver.quit()
    

    yield之前的为setup方法, 进入范围时执行,yield之后的为teardown方法,离开范围时执行

    注: 如果yield前的setup操作出现异常,teardown操作将不再执行, 如果setup操作不稳定,可以使用addfinalizer方法确保teardown操作一定被执行

    执行顺序

    • setup执行顺序按范围从大到小, teardown方法按相反顺序

    独立的fixture方法(供某个/某些用例单独使用)

    db=Db()  # 封装的数据对象, 详见之前的文章
    
    @pytest.fixture()  # 声明为fixture(测试准备/清理)方法
    def del_user():
        db.del_user_if_exist("临渊")  # setup
        yield
        db.del_user_if_exist("临渊")  # teardown
    
    
    def test_user_reg(del_user):  # 将fixture方法函数名作为参数使用
        ...                       # 和使用@pytest.mark.usefixtures('del_user')作用相同
    
    
    

    向fixture方法传递参数及使用返回结果

    待补充
    ...
    
    

    使用conftest.py(固定文件名),集中管理fixtures方法

    待补充
    ...
    
    

    灵活的运行控制

    通过pytest ...命令,可以实现非常灵活的执行控制

    • 运行目录及子包下的所有用例: pytest 目录名
    • 运行指定模块所有用例: pytest test_reg.py
    • pytest test_reg.py::TestClass::test_method 运行指定模块指定类指定用例
    • 运行名称包含指定表达式的用例:-k 表达式(支持and or not),如pytest -k "test_a and test_b"
    • 运行指定标签(mark)的用例: -m 标签(支持and or not), 如pytest -m "apitest and level1"
    • 遇到失败后停止:-x/--exitfirst 首次失败后退出(可用于保留出错现场) --maxfails=3 3次失败后退出
    • 执行上次失败的用例 --lf/--last-failed
    • 先执行上次失败的用例,再执行成功的用例 --ff/--failed-first
    • 只收集用例,不执行 --collect-only
    • 显示执行最慢的前N条用例:--durations=N

    其它常用参数

    • -q: 安静模式, 不输出环境信息
    • -v: 丰富信息模式, 输出更详细的用例执行信息
    • -s: 显示程序中的print/logging输出
    • pytest --resultlog=./log.txt 生成log
    • pytest --junitxml=./log.xml 生成xml报告

    丰富的插件

    • pytest-html 生成html报告插件

    pip3 install pytest-html

    pytest test_reg.py --html=report.html
    
    • pytest-timeout 限制用例超时时间

    pip3 install pytest-timeout

    @pytest.mark.timeout(60)
    def test_user_reg():  # 当前用例限定60s超时
       ...
    

    pytest --timeout=300限定所有用例

    • pytest-rerunfailures 失败重试

    pip3 install pytest-rerunfailures

    @pytest.mark.flaky(reruns=5, reruns_delay=1)  # 如果失败则延迟1s后重跑
    def test_user_reg()  # 最多重跑5次, reruns_delay可以不传
        ....
    

    pytest --reruns 5 --reruns-delay 1

    • pytest-xdist 多CPU分发并行执行用例

    pip3 install pytest-xdist

    待补充
    ...
    
    
    • 其它
      • pytest-selenium
      • pytest-bdd

    相关文章

      网友评论

        本文标题:Pytest自动化实践教程1-Pytest基础使用

        本文链接:https://www.haomeiwen.com/subject/wvwovqtx.html