• app自动化05-Pytest使用


    Pytest安装和介绍

    介绍

    pytest是python的一种单元测试框架,同自带的Unittest测试框架类似,相比于Unittest框架使用起来更简洁,效率更高。
    特点
    1.非常容易上手,入门简单,文档丰富,文档中有很多实例可以参考
    2.支持简单的单元测试和复杂的功能测试
    3.支持参数化
    4.执行测试过程中可以将某些测试跳过,或者对某些预期失败的Case标记成失败
    5.支持重复执行失败的Case
    6.支持运行由Nose , Unittest编写的测试Case
    7.具有很多第三方插件,并且可以自定义扩展
    8.方便的和持续集成工具集成

    Pytest安装

    1.mac/linux:sudo pip3 install -U pytest # -U:可以理解为--upgrade,表示已安装就升级为最新版本
    2.管理员方式运行cmd:pip3 install -U pytest
    安装成功校验 
    1.进入命令行
    2.运行:pytest --version # 会展示当前已安装版本

    Pytest运行

    Hello Pytest

        # file_name: login.py
        import pytest # 引入pytest包
        def test_a(): # test开头的测试函数
            print("------->test_a")
            assert 1 # 断言成功
        def test_b():
            print("------->test_b")
            assert 0 # 断言失败
        if __name__ == '__main__':
            # pytest.main("-s  test_abc.py") # 调用pytest的main函数执行测试
            pytest.main(["-s", "login.py"])
    执行结果:
    test_login.py 
    ------->test_a
    . # .(代表成功)
    ------->test_b
    F # F(代表失败)

    Pytest运行方式

    1、测试类主函数模式
    pytest.main(["-s", "test_abc.py"])
    2、命令行模式
    pytest -s 文件路径/测试文件名
    例如:
    pytest -s login.py

    setup和teardown函数

    概述
    1.setup和teardown主要分为:函数级、类级、模块级、功能级。
    2.存在于测试类内部

    函数级别

    运行于测试方法的始末,即:运行一次测试函数会运行一次setup和teardown
    代码示例:
            import pytest
            class TestABC:
                # 函数级开始
                def setup(self):
                    print("------->setup_method")
                # 函数级结束
                def teardown(self):
                    print("------->teardown_method")
                def test_a(self):
                    print("------->test_a")
                    assert 1
                def test_b(self):
                    print("------->test_b")
            if __name__ == '__main__':
                pytest.main("-s  test_abc.py")
        执行结果:
            test_abc.py 
            ------->setup_method # 第一次 setup()
            ------->test_a
            .
            ------->teardown_method # 第一次 teardown()
            ------->setup_method # 第二次 setup()
            ------->test_b
            .
            ------->teardown_method # 第二次 teardown()

    类级别

    运行于测试类的始末,即:在一个测试内只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数。
    代码示例:
            import pytest
            class TestABC:
                # 测试类级开始
                def setup_class(self):
                    print("------->setup_class")
                # 测试类级结束
                def teardown_class(self):
                    print("------->teardown_class")
                def test_a(self):
                    print("------->test_a")
                    assert 1
                def test_b(self):
                    print("------->test_b")
                    assert 0
            if __name__ == '__main__':
                pytest.main("-s  test_abc.py")
        执行结果:
            test_abc.py 
            ------->setup_class # 第一次 setup_class()
            ------->test_a
            .
            ------->test_b
            F 
            ------->teardown_class # 第一次 teardown_class()

    Pytest配置文件

    pytest的配置文件通常放在测试目录下,名称为pytest.ini,命令行运行时会使用该配置文件中的配置.

    配置pytest命令行运行参数

    [pytest]
    addopts = -s ... # 空格分隔,可添加多个命令行参数 -所有参数均为插件包的参数

    配置测试搜索的路径

    [pytest]
    testpaths = ./scripts  # 当前目录下的scripts文件夹 -可自定义

    配置测试搜索的文件名

    [pytest]
    python_files = test_*.py  
    # 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件 -可自定义

    配置测试搜索的测试类名

    [pytest]
    python_classes = Test*  
    # 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件中,以Test_开头的类 -可自定义

    配置测试搜索的测试函数名

    [pytest]
    python_functions = test_*  
    # 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件中,以Test_开头的类内,以test_开头的方法 -可自定义

    Pytest常用插件

    插件列表网址:https://plugincompat.herokuapp.com
    包含很多插件包,大家可依据工作的需求选择使用。
    前置条件:
            1.文件路径:
                - Test_App
                - - test_abc.py
                - - pytest.ini
            2.pyetst.ini配置文件内容:
                [pytest]
                # 命令行参数
                addopts = -s
                # 若没有配置搜索路径名,则默认搜索和pytest.ini同级的路径
                # 搜索文件名
                python_files = test_*.py
                # 搜索的类名
                python_classes = Test*
                # 搜索的函数名
                python_functions = test_*

    Pytest测试报告

    通过命令行方式,生成xml/html格式的测试报告,存储于用户指定路径。
    插件名称:pytest-html
        安装方式:
            1.安装包方式 python setup.py install 
            2.命令行 pip3 install pytest-html
        使用方法:
            命令行格式:pytest --html=用户路径/report.html
        示例:
            import pytest
            class TestABC:
                def setup_class(self):
                    print("------->setup_class")
                def teardown_class(self):
                    print("------->teardown_class")
                def test_a(self):
                    print("------->test_a")
                    assert 1 # 断言成功
                def test_b(self):
                    print("------->test_b")
                    assert 0 # 断言失败
        运行方式:
            1.修改Test_App/pytest.ini文件,添加报告参数,即:addopts = -s --html=./report.html 
                # -s:输出程序运行信息
                # --html=./report.html 在当前目录下生成report.html文件
                ⚠️ 若要生成xml文件,可将--html=./report.html 改成 --html=./report.xml
            2.命令行进入Test_App目录
            3.执行命令: pytest
            执行结果:
            1.在当前目录会生成assets文件夹和report.html文件
        

    Pytest控制函数执行顺序

    函数修饰符的方式标记被测试函数执行的顺序.
    插件名称:pytest-ordering
        安装方式:
            1.安装包方式 python setup.py install 
            2.命令行 pip3 install pytest-ordering
        使用方法:
            1.标记于被测试函数,@pytest.mark.run(order=x)
            2.根据order传入的参数来解决运行顺序
            3.order值全为正数或全为负数时,运行顺序:值越小,优先级越高
            4.正数和负数同时存在:正数优先级高
    默认情况下,pytest是根据测试方法名从上至下执行的,可以通过第三方插件包改变其运行顺序。
    默认执行方式
        示例:
            import pytest
            class TestABC:
                def setup_class(self):
                    print("------->setup_class")
                def teardown_class(self):
                    print("------->teardown_class")
                def test_a(self):
                    print("------->test_a")
                    assert 1
                def test_b(self):
                    print("------->test_b")
                    assert 0
            if __name__ == '__main__':
                pytest.main("-s  test_abc.py")
        执行结果:
            test_abc.py 
            ------->setup_class
            ------->test_a # 默认第一个运行
            .
            ------->test_b # 默认第二个运行
            F
            ------->teardown_class
    
        示例:
            import pytest
            class TestABC:
                def setup_class(self):
                    print("------->setup_class")
    
                def teardown_class(self):
                    print("------->teardown_class")
                @pytest.mark.run(order=2)
                def test_a(self):
                    print("------->test_a")
                    assert 1
    
                @pytest.mark.run(order=1)
                def test_b(self):
                    print("------->test_b")
                    assert 0
            if __name__ == '__main__':
                    pytest.main("-s  test_abc.py")
        执行结果:
            test_abc.py
            ------->setup_class
            ------->test_b # order=1 优先运行
            F
            ------->test_a # order=2 晚于 order=1 运行
            .
            ------->teardown_class

    Pytest失败重试

    通过命令行方式,控制失败函数的重试次数。
        插件名称:pytest-rerunfailures
        安装方式:
            1.安装包方式 python setup.py install 
            2.命令行 pip3 install pytest-rerunfailures
        使用方法:
            命令行格式:pytest --reruns n # n:为重试的次数
        示例:
        import pytest
        class Test_ABC:
            def setup_class(self):
                print("------->setup_class")
            def teardown_class(self):
                print("------->teardown_class")
            def test_a(self):
                print("------->test_a")
                assert 1
            def test_b(self):
                print("------->test_b")
                assert 0 # 断言失败
        运行方式:
            1.修改Test_App/pytest.ini文件,添加失败重试参数,即:addopts = -s  --reruns 2 --html=./report.html 
                # -s:输出程序运行信息
                # --reruns 2 :失败测试函数重试两次
                # --html=./report.html 在当前目录下生成report.html文件
            2.命令行进入Test_App目录
            3.执行命令: pytest
        执行结果:
            1.在测试报告中可以看到两次重试记录
    注意:
    如果有一次成功了,那么就不会再进行失败重试了。

    Pytest高级用法

    跳过测试函数

    根据特定的条件,不执行标识的测试函数.
        方法:
            skipif(condition, reason=None)
        参数:
            condition:跳过的条件,必传参数
            reason:标注原因,必传参数
        使用方法:
            @pytest.mark.skipif(condition, reason="xxx")
        示例:
            import pytest
            class TestABC:
                def setup_class(self):
                    print("------->setup_class")
                def teardown_class(self):
                    print("------->teardown_class")
                def test_a(self):
                    print("------->test_a")
                    assert 1
                @pytest.mark.skipif(condition=2>1,reason = "跳过该函数") # 跳过测试函数test_b
                def test_b(self):
                    print("------->test_b")
                    assert 0
        执行结果:
            test_abc.py 
            ------->setup_class
            ------->test_a #只执行了函数test_a
            .
            ------->teardown_class
             # 跳过函数

    标记为预期失败的函数

    标记测试函数为失败函数
        方法:
            xfail(condition=None, reason=None, raises=None, run=True, strict=False)
        常用参数:
            condition:预期失败的条件,必传参数
            reason:失败的原因,必传参数
        使用方法:
            @pytest.mark.xfail(condition, reason="xx")
    示例:
            import pytest
            class TestABC:
                def setup_class(self):
                    print("------->setup_class")
                def teardown_class(self):
                    print("------->teardown_class")
                def test_a(self):
                    print("------->test_a")
                    assert 1
                @pytest.mark.xfail(2 > 1, reason="标注为预期失败") # 标记为预期失败函数test_b
                def test_b(self):
                    print("------->test_b")
                    assert 0
        执行结果:
            test_abc.py 
            ------->setup_class
            ------->test_a
            .
            ------->test_b
            ------->teardown_class
            x  # 失败标记

    函数数据参数化

    方便测试函数对测试数据的获取。
    方法:
        parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
    常用参数:
        argnames:参数名
        argvalues:参数对应值,类型必须为list
                    当参数为一个时格式:[value]
                    当参数个数大于一个时,格式为:[value1,value2,value3,value4,....]
        使用方法:
            @pytest.mark.parametrize(argnames,argvalues)
            ⚠️ 参数值为N个,测试方法就会运行N次
        单个参数示例:
            import pytest
            class TestABC:
                def setup_class(self):
                    print("------->setup_class")
                def teardown_class(self):
                    print("------->teardown_class")
    
                @pytest.mark.parametrize("a",[3,6]) # a参数被赋予两个值,函数会运行两遍
                def test_a(self,a): # 参数名必须和parametrize里面的参数名一致
                    print("test data:a=%d"%a)
                    assert a%3 == 0
        执行结果:
            test_abc.py 
            ------->setup_class
            test data:a=3 # 运行第一次取值a=3
            .
            test data:a=6 # 运行第二次取值a=6
            . 
            ------->teardown_class
    多个参数示例:
            import pytest
            class TestABC:
                def setup_class(self):
                    print("------->setup_class")
                def teardown_class(self):
                    print("------->teardown_class")
                
                 # 参数a,b是一个元祖里面元素,函数会运行两遍。由于值类型是列表,列表里面元素是元组
                 # 所以接收的值的类型也需要为元组,并且和列表里面的元祖格式保持一致
                @pytest.mark.parametrize("a,b",[(1,2),(0,3)])
                def test_a(self,a,b): # 参数必须和parametrize里面的参数一致
                    print("test data:a=%d,b=%d"%(a,b))
                    assert a+b == 3
                @pytest.mark.parametrize(('x','y','z'),[('a',1,5),('b',2,4),('c',6,7)])
                def test_search2(self, x, y,z):
                    print(x,y,z)
        执行结果:
            test_abc.py 
            ------->setup_class
            test data:a=1,b=2 # 运行第一次取值 a=1,b=2
            .
            test data:a=0,b=3 # 运行第二次取值 a=0,b=3
            .
            a 1 5
            .b 2 4
            .c 6 7
            .
            ------->teardown_class
  • 相关阅读:
    洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)
    洛谷P4502 [ZJOI2018]保镖(计算几何+三维凸包)
    [Codeforces1137D]Cooperative Game
    洛谷P2287 [HNOI2004]最佳包裹(三维凸包)
    洛谷P4724 【模板】三维凸包
    洛谷P4526 【模板】自适应辛普森法2(Simpson法)
    A + B Problem
    Java中方法next()和nextLine()的区别
    发现环
    分考场
  • 原文地址:https://www.cnblogs.com/st998/p/13803701.html
Copyright © 2020-2023  润新知