• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

PyTest测试用例创建和使用

武飞扬头像
单叼红中
帮助1

对于实现的接口代码,如登陆,我们常常会有多种情况的登陆,但其实本质就是每次发送登陆的请求参数不一样,我们如何只写一个测试接口,实现我们多条不同数据的登陆呢?

1、固件/前后置处理方法

'''
pytest fixture仓库 ,全部是都fixture内容
'''

import pytest

from global_session import global_session as s


@pytest.fixture()
def login():
    '''
    封装登录 前置步骤
    :return:
    '''

    url = "  "
    x = {
        "username": "  ",
        "password": "  ",
        "verifycode": "  "
    }
    s.post(url = url , data = x) # 发送post请求登录

    print(id(s))


    yield

    # 退出
    s.close()

学新通

核心配置文件

[pytest]
addopts = -v -s  --setup-show  test_cases/test_batch_upload.py --alluredir=temp --clean-alluredir
testpaths = ./test_cases

markers = {smoke: smoking test case}

学新通

使用@pytest.fixture()装饰器实现部分用例的前后置

参数解释: 

注意事项:

  1. 如果一个测试用例,用到了多个fixture(少见),次序是,范围大的先执行,相同级别的。从左到右执行。

  2. fixture可以使用相同级别或者 级别高的fixture

  3. class级别的,并不是说,只能在class 里面的测试方法可以用!!!包括测试函数也可以用(行为 = 函数级别),只是测试用例封装在类里面。多个类里面的测试用例,class级别的fixture只会执行一次

4、使用usefixture装饰器指定使用fixture

4、实现参数化

(1)使用@pytest.fixture() 实现参数化

import pytest
# 数据fixture  返回测试数据
@pytest.fixture(params=[{"name":"zs"}, [1,2,3], "c"])
def my_fixture(request):
    print("这是我自己定义的前置的方法")
    yield request.param  # # 通过yield关键字 在后面填写后置的方法
    print("这是我自己定义的后置的方法")

class TestLogin():

    @pytest.mark.user
    def testaddsale(self, my_fixture):
        print("------->test_b------------>",my_fixture)
        assert 1  # 断言失败

if __name__ == '__main__':
    pytest.main(["-vs", "test_aaa.py"])  # 调用pytest的main函数执行测试

(2)使用@pytest.mark.parametrize()实现参数化

  • scope表示的是被@pytest.fixture标记的方法的作用域

    • function 默认 针对函数

    • class 针对类

    • module 针对模块

    • package 针对包(没有实现)

    • session 针对整个测试会话 开始执行pytest到结束 算一个测试会话

  • params 实现参数化

  • autouse=True 自动使用,默认是false,当为True时表示在它所作用域的范围内都会自动使用该装置

  • ids 当使用params参数化时,给每一个值设置一个变量名。意义不大

  • name 给被@pytest.fixture()标记的方法取一个别名,意义不大,起了别名后,原来的函数名称就不能使用

  • 关于形参中出现 / * 的意义 python函数参数中的/和*是什么意思? - 知乎

  • fixture默认是函数级别的,还有session级别,这2个最常用。module级别的也偶尔见到。

  • 调用fixture的四种方法

  • (1)函数或类里面方法直接传fixture的名称作为用例函数参数名称

    import pytest
    
    @pytest.fixture()
    def my_fixture():
        print("这是我自己定义的前置的方法")
        yield  # 通过yield关键字 在后面填写后置的方法
        print("这是我自己定义的后置的方法")
    
    class TestLogin():
        @pytest.mark.smoke
        def testsales(self):  # test开头的测试函数
            print("------->test_a")
            assert 1  # 断言成功
    
        @pytest.mark.user
        def testaddsale(self,my_fixture):
            print("------->test_b")
            assert 0  # 断言失败
    
    
    if __name__ == '__main__':
        pytest.main(["-s","test_aaa.py"])  # 调用pytest的main函数执行测试

    (2)使用装饰器@pytest.mark.usefixtures(fixture_name)修饰需要运行的用例 。

    usefixtures装饰器除了可以装饰函数和类里面的方法外,还可以装饰类,而且其优先级还比传参方式的优先级高

  • 验证 @pytest.mark.usefixtures 和传参的形式的优先级

    # 验证 @pytest.mark.usefixtures 和传参的形式的优先级
    @pytest.fixture(scope="function")
    def function1_fixture(request):
        print("这是我自己定义的function1前置的方法")
        yield   # # 通过yield关键字 在后面填写后置的方法
        print("这是我自己定义的function1后置的方法")
    @pytest.fixture(scope="function")
    def function2_fixture(request):
        print("这是我自己定义的function2前置的方法")
        yield   # # 通过yield关键字 在后面填写后置的方法
        print("这是我自己定义的function2后置的方法")
    
    class TestLogin():
    
        @pytest.mark.usefixtures('function1_fixture')
        def testsales(self,function2_fixture):  # test开头的测试函数
            print("------->test_a")
            assert 1  # 断言成功
    
        def testaddsale(self):
            print("------->test_b")
            assert 0  # 断言失败
    
    class TestLogin1():
        def testsales(self):  # test开头的测试函数
            print("------->test_a")
            assert 1  # 断言成功
        def testaddsale(self):
            print("------->test_b------------>")
            assert 1  # 断言失败
    
    if __name__ == '__main__':
        pytest.main(["-vs", "test_aaa.py"])  # 调用pytest的main函数执行测试
    

    (3)验证类 使用fixture 及autouse的使用 及 不同级别作用域的fixture的优先级

    import pytest
    
    @pytest.fixture(scope="module",autouse=True)
    def module_fixture(request):
        print("这是我自己定义的module前置的方法")
        yield   # # 通过yield关键字 在后面填写后置的方法
        print("这是我自己定义的module后置的方法")
    
    @pytest.fixture(scope="class")
    def class_fixture(request):
        print("这是我自己定义的class前置的方法")
        yield   # # 通过yield关键字 在后面填写后置的方法
        print("这是我自己定义的class后置的方法")
    
    @pytest.fixture(scope="function")
    def function1_fixture(request):
        print("这是我自己定义的function1前置的方法")
        yield   # # 通过yield关键字 在后面填写后置的方法
        print("这是我自己定义的function1后置的方法")
    @pytest.fixture(scope="function")
    def function2_fixture(request):
        print("这是我自己定义的function2前置的方法")
        yield   # # 通过yield关键字 在后面填写后置的方法
        print("这是我自己定义的function2后置的方法")
    
    @pytest.mark.usefixtures('class_fixture')
    class TestLogin():
    
        @pytest.mark.usefixtures('function1_fixture')
        def testsales(self,function2_fixture):  # test开头的测试函数
            print("------->test_a")
            assert 1  # 断言成功
    
        def testaddsale(self):
            print("------->test_b")
            assert 0  # 断言失败
    
    class TestLogin1():
        def testsales(self):  # test开头的测试函数
            print("------->test_a")
            assert 1  # 断言成功
        def testaddsale(self):
            print("------->test_b------------>")
            assert 1  # 断言失败
    
    
    if __name__ == '__main__':
        pytest.main(["-vs", "test_aaa.py"])  # 调用pytest的main函数执行测试
    
  • 不同作用域的fixture,遵循:session > package > module > class > function

  • 相同级别的fixture,且有依赖关系的fixture:遵循fixture之间的依赖关系 fixture 可以使用同级别或者以上级别的fixture

  • fixture设置autouse=True

  • 使用conftest.py文件共享fixture实例(主要用户项目的全局登陆,模块的全局处理,说白了就是其他地方都会调用的fixture可以写在conftest.py中)

    • conftest.py单独用来存放固件的一个配置文件名称不能更改

    • 作用:可以在不同的py文件中使用同一个fixture函数。使用的时候也不需要导入conftest.py,pytest会自动寻找

    • 一个工程下可以建多个conftest.py的文件,不同子目录下也可以放conftest.py的文件

    • conftest.py文件的作用域是当前包内(包括子包)。如果有函数调用fixture,会优先从当前测试类中寻找,然后是模块(.py文件)中,接着是当前包中寻找(conftest.py中),如果没有再找父包直至根目录;如果我们要声明全局的conftest.py文件,我们可以将其放在项目根目录下。

  • 相同级别的fixture,同时用装饰器和参数传递方式调用: usefixtures装饰的优先级高于传参形式的fixture

  • 相同级别的fixture,都使用装饰器调用时,先执行的放底层,后执行的放上层

  • 里面写两个参数,第一个参数是字符串,如果要表示多个参数每个参数中间用逗号隔开,第二个参数是list,表示传入的参数化数据

    import pytest
    
    
    class TestLogin():
    
        @pytest.mark.parametrize("data",[1,2,3])
        def test_1(self,data):  # test开头的测试函数
            print(f"------->test_1---------->data:{data}")
    
    
        @pytest.mark.parametrize("name,age",[['zs',18],['ls',15]])
        def test_2(self,name,age):
            print(f"------->test_2------->name:{name}---------age:{age}")
    
        @pytest.mark.parametrize("data",[['zs',18],['ls',15]])
        def test_3(self,data:list):
            print(f"------->test_3------->data:{data},data的type:{type(data)}")
    
        @pytest.mark.parametrize("data",[{"name":"zs","age":18},{"name":"ls","age":20}])
        def test_4(self,data:dict):
            print(f"------->test_4------->data:{data},data的type:{type(data)}")
    
    
    
    if __name__ == '__main__':
        pytest.main(["test_aaa.py"])  # 调用pytest的main函数执行测试
    
    1. 装饰器有2个必填参数, 第一个参数,是字符串 ,第二个参数是列表( 元组,列表,多个字典)

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggbfch
系列文章
更多 icon
同类精品
更多 icon
继续加载