ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

测试框架pytest(四)

2022-04-26 16:00:28  阅读:199  来源: 互联网

标签:框架 fixture assert pytest 测试 test login def


接上一篇,本章讲pytest的fixture

很多测试框架里的setup、teardown可以实现在执行用例前或结束后加入一些操作,但这种都是针对整个脚本全局生效的。
如果有以下场景:用例 1 需要先登录,用例 2 不需要登录,用例 3 需要先登录。很显然无法用 setup 和 teardown 来实现。fixture可以让我们自定义测试用例的前置条件以及结束后的后置处理动作,并且可以跨文件使用。

另外conftest.py 配置里可以实现数据共享,不需要 import 就能自动找到fixture,还可以自定义fixture的作用域

语法如下:

fixture(callable_or_scope=None, *args, scope="function", params=None, autouse=False, ids=None, name=None)
  • scope:fixture的作用域,默认为function,优先级从高到低,session-->module–->class–->function 。
  • autouse:默认:False,需要用例手动调用该fixture;如果是True,所有作用域内的测试用例都会自动调用该fixture;
  • name:装饰器的名称,同一模块的fixture相互调用建议写不同的name。

如下是无参使用例子


#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest
from get_data import get_data


def add_demo(a, b):
return a+b


@pytest.fixture()
def login():
print('execute before')


@pytest.mark.smoke
class TestDemo:
@pytest.mark.parametrize("a,b,expected", get_data(),
ids=["level1", "level2", "level3"])
def test_one(self, a, b, expected):
assert add_demo(a, b) == expected

def test_two(self, login):
assert 2 != 3

@pytest.mark.usefixtures("login")
def test_three(self):
assert 4 != 3


if __name__ == "__main__":
pytest.main(['test_demo.py', '-v', '-s', '-m', 'smoke'])
 

上述代码中我们通过2种方式来演示fixture的使用,看个人喜好灵活运用。

出于可维护性方面考虑,我们把fixture放在conftest.py文件里进行维护,文件名称是固定的,这样不用引入就可以使用,然后使用范围根据conftest.py的存放位置以及fixture的作用域来确定,改造的conftest.py代码如下:

import pytest


@pytest.fixture()
def login_se():
    print('just another login')

然后原代码改造如下:

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest
from get_data import get_data


def add_demo(a, b):
    return a+b


@pytest.fixture()
def login():
    print('execute before')


@pytest.mark.smoke
class TestDemo:
    @pytest.mark.parametrize("a,b,expected", get_data(),
                             ids=["level1", "level2", "level3"])
    def test_one(self, a, b, expected):
        assert add_demo(a, b) == expected

    def test_two(self, login):
        assert 2 != 3

    @pytest.mark.usefixtures("login")
    def test_three(self):
        assert 4 != 3

    @pytest.mark.usefixtures("login_se")
    def test_four(self):
        assert 6 != 9

    def test_five(self, login_se):
        assert 9 != 0


if __name__ == "__main__":
    pytest.main(['test_demo.py', '-v', '-s', '-m', 'smoke'])

然后我们有时候需要在fixture里传入参数,现在演示这种情况,conftest.py代码如下:

 

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest


@pytest.fixture()
def login_se():
    print('just another login')


@pytest.fixture(scope='module')
def login_with_param(request):
    return request.param

改造后的test_demo.py代码如下:

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest
from get_data import get_data


def add_demo(a, b):
    return a+b


@pytest.fixture()
def login():
    print('execute before')


@pytest.mark.smoke
class TestDemo:
    @pytest.mark.parametrize("a,b,expected", get_data(),
                             ids=["level1", "level2", "level3"])
    def test_add_demo(self, a, b, expected):
        assert add_demo(a, b) == expected

    def test_two(self, login):
        assert 2 != 3

    @pytest.mark.usefixtures("login")
    def test_three(self):
        assert 4 != 3

    @pytest.mark.usefixtures("login_se")
    def test_four(self):
        assert 6 != 9

    def test_five(self, login_se):
        assert 9 != 0

    @pytest.mark.parametrize("login_with_param", [{"user": "lucy", "password": "123456"}],
                             ids=["level1"], indirect=True)
    def test_add_demo(self, login_with_param):
        username = login_with_param['user']
        password = login_with_param['password']
        assert username == 'lucy'
        assert password == '123456'


if __name__ == "__main__":
    pytest.main(['test_demo.py', '-v', '-s', '-m', 'smoke'])

到这里后,我们就已经实现了fixture有参的方式,但是目前为止还没有实现teardown的功能,可以用yield来实现,conftest.py代码如下:

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest


@pytest.fixture()
def login_se():
    print('just another login')


@pytest.fixture(scope='module')
def login_with_param(request):
    return request.param


@pytest.fixture(scope='module')
def login_with_params(request):
    print('开始前运行')
    yield request.param
    print('结束后运行')

改造后的test_demo.py的test_seven 代码如下:

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest
from get_data import get_data


def add_demo(a, b):
    return a+b


@pytest.fixture()
def login():
    print('execute before')


@pytest.mark.smoke
class TestDemo:
    @pytest.mark.parametrize("a,b,expected", get_data(),
                             ids=["level1", "level2", "level3"])
    def test_add_demo(self, a, b, expected):
        assert add_demo(a, b) == expected

    def test_two(self, login):
        assert 2 != 3

    @pytest.mark.usefixtures("login")
    def test_three(self):
        assert 4 != 3

    @pytest.mark.usefixtures("login_se")
    def test_four(self):
        assert 6 != 9

    def test_five(self, login_se):
        assert 9 != 0

    @pytest.mark.parametrize("login_with_param", [{"user": "lucy", "password": "123456"}],
                             ids=["level1"], indirect=True)
    def test_six(self, login_with_param):
        username = login_with_param['user']
        password = login_with_param['password']
        assert username == 'lucy'
        assert password == '123456'

    @pytest.mark.parametrize("login_with_params", [{"user": "lucy", "password": "123456"}],
                             ids=["level1"], indirect=True)
    def test_seven(self, login_with_params):
        username = login_with_params['user']
        password = login_with_params['password']
        assert username == 'lucy'
        assert password == '123456'


if __name__ == "__main__":
    pytest.main(['test_demo.py', '-v', '-s', '-m', 'smoke'])

上述方式是将fixture和parametrize结合起来使用,这样子会看起来比较不友好,所以把参数给到conftest.py里,改造如下:

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest


@pytest.fixture()
def login_se():
    print('just another login')


@pytest.fixture(scope='module')
def login_with_param(request):
    return request.param


@pytest.fixture(scope='module')
def login_with_params(request):
    print('开始前运行')
    yield request.param
    print('结束后运行')


@pytest.fixture(params=[{'user': 'lucy', 'password': '123456'}])
def login_and_logout(request):
    print('开始前运行的前置处理代码')
    yield request.param
    print('结束后运行的收尾处理代码')

然后测试类的test_eight改造如下:

#!/usr/bin/env python
# -*-coding:utf-8 -*-
import pytest
from get_data import get_data


def add_demo(a, b):
    return a+b


@pytest.fixture()
def login():
    print('execute before')


@pytest.mark.smoke
class TestDemo:
    @pytest.mark.parametrize("a,b,expected", get_data(),
                             ids=["level1", "level2", "level3"])
    def test_add_demo(self, a, b, expected):
        assert add_demo(a, b) == expected

    def test_two(self, login):
        assert 2 != 3

    @pytest.mark.usefixtures("login")
    def test_three(self):
        assert 4 != 3

    @pytest.mark.usefixtures("login_se")
    def test_four(self):
        assert 6 != 9

    def test_five(self, login_se):
        assert 9 != 0

    @pytest.mark.parametrize("login_with_param", [{"user": "lucy", "password": "123456"}],
                             ids=["level1"], indirect=True)
    def test_six(self, login_with_param):
        username = login_with_param['user']
        password = login_with_param['password']
        assert username == 'lucy'
        assert password == '123456'

    @pytest.mark.parametrize("login_with_params", [{"user": "lucy", "password": "123456"}],
                             ids=["level1"], indirect=True)
    def test_seven(self, login_with_params):
        username = login_with_params['user']
        password = login_with_params['password']
        assert username == 'lucy'
        assert password == '123456'

    def test_eight(self, login_and_logout):
        username = login_and_logout['user']
        password = login_and_logout['password']
        assert username == 'lucy'
        assert password == '123456'


if __name__ == "__main__":
    pytest.main(['test_demo.py', '-v', '-s', '-m', 'smoke'])

至此,fixture就讲解完毕,上述代码比较简陋,还应该做较好的封装,提高代码的可读性

标签:框架,fixture,assert,pytest,测试,test,login,def
来源: https://www.cnblogs.com/doumayi/p/16194767.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有