pytest+allure

Knowledge point 1:

1. Read the test result information

  • Passed means passed, there is an abbreviation.

  • failed means failure, there is an abbreviation F

2. Command line parameters

  • -h: help

  • -version: version information

3. Test case naming rules:

  • Test functions must start with test

  • A test class must start with Test, but a test class cannot have an init method

  • Test files must start with test/Test or end with test/Test

4. Run the specified test case: specified file [::class name][::function name]

  • By default, the rule of use case search is that pytest executes the current directory and subdirectories (traversal)

  • Specify the class name to run: pytest filename::classname

  • Specify the function name to run: pytest file name::class name::function name

  • Specify the function name to run: pytest filename::functionname

  • Run the file in the specified directory: pytest directory name\file name::function name

  • pytest .\test_a02\test_a02_a.py::test_001 (class test_001 under test_a02_a.py file; terminal)

5. pytest.main() execution use case

  • Command line parameters args, list type, composed of one or more str, separated by commas
import pytest


def test_a01():
    assert 1 == 1


if __name__ == '__main__':  # 运行测试的话,需要在pycharm中设置python集成工具=>unittest
    # pytest.main()  # 等价于pytest命令
    # pytest.main([__file__])  # 测试当前文件
    # pytest.main(['--version'])
    pytest.main['-sv', __file__]  # 多参数调用

6. Run the specified test case - k parameter

  • Match the name part of the test class or test method

  • Case Sensitive

  • logic operation

expression illustrate
-k login Test the use case that contains login in the class name or function name
-k not login does not contain login
-k login and success Contains login and contains success
-k login or success Contains login or success
-k login and not success Contains login but does not contain success
import pytest


def test_login_success():
    pass


def test_login_failed():
    pass


def test_logout_success():
    pass


def test_logout_failed():
    pass


if __name__ == '__main__':
    pytest.main(['-k success and not failed', '--collect-only', __file__])  # –collect-only 含义:展示给定配置下哪些测试用例会被运行

insert image description here

7、pytest.mark.skip/skipif

  • conditionally ignore skipif
import pytest, sys


@pytest.mark.skipif(1 == 1, reason='if 1==1 skip this')  # 条件满足就忽略测试  reason:标注原因
def test_a01_1(reason='i wanna skip this case'):
    pass


@pytest.mark.skipif(1 == 2, reason='if 1==2 skip this')  # 条件不满足不会跳过
def test_a01_2():
    pass


@pytest.mark.skipif(sys.platform == 'linux', reason='if linux skip this')  # sys.platform 操作系统平台标识
def test_a01_3():
    pass


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

  • Output result s
import pytest


@pytest.mark.skip
def test_a01_1(reason='i wanna skip this case'):
    pass


def test_a01_2():
    pass


if __name__ == '__main__':
    pytest.main(['-sv', __file__])
    # pytest.main(['--collect-only', __file__])  # 能被采集
    # pytest.main([__file__])  # 输出s

insert image description here

import pytest

pytestmark = pytest.mark.skip('skip all cases')  # pytestmark 这个名字不可更改


def test_a01_1():
    pass


def test_a01_2():
    pass


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

import pytest


def test_a01_1():
    arrow = pytest.importorskip('arrow')  # 这个库在当前环境下没有的话会报错,有会自动导入
    nowtime = arrow.now().format('YYYY-MM-DD')  # 获取当前时间
    print(nowtime)


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

8. pytest.mark.parameterizeparameterization

  • When testing a test function, it is common to pass multiple sets of parameters to the function. For example, to test account login, we need to simulate all kinds of strange account passwords. Of course, we can write these parameters inside the test function for traversal. However, although there are many parameters, it is still a test. When a certain set of parameters causes the assertion to fail, the test is terminated. Through exception capture, we can ensure that all parameters are fully executed, but it takes a lot of extra work to analyze the test results

  • In pytest, we have a better solution, which is parameterized testing, that is, each set of parameters executes a test independently. The tool used is pytest.mark.parametrize(argnames, argvalues)

  • Analyze the source code of parameterize, and you can see the parameters to be used when calling

parameter meaning
argnames Required, parameter names, comma-separated strings, indicating one or more parameter names, or a list or tuple of strings
argvalues Required, a list of parameter values
indirect When it is True, argnames must be the function name of a fixture, and the value of argvalues ​​is passed into the corresponding fixture, which is equivalent to @pytest.fixture(params=), and the default is False
ids Use case id, mark the execution name of the sub-use case, consistent with the number of argvalues, if not specified, it will be automatically generated, the default is None
scope The scope of action, similar to the scope parameter in the fixture, indicates the scope of the parameter, and the scope is used to group tests by parameter instances. It will override the scope defined by any fixture function, allowing dynamic scope to be set using the test context or configuration

The parameters match, argnames must be consistent with the parameters of the test function, otherwise an error will be reported

import pytest


@pytest.mark.parametrize('arg0', [0, 1])  # (0, 1)   '01' 不推荐用
def test_a01_1(arg0):
    print(arg0)


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

multiple parameters

import pytest


@pytest.mark.parametrize('arg0, arg1', [(0, 1), (2, 2), (3, 4)])  # argvalues 往往是通过其他程序读取到
def test_a01_1(arg0, arg1):
    print(f'arg0 is {
      
      arg0},arg1 is {
      
      arg1}')
    assert arg0 == arg1


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

multiple decorators

import pytest


@pytest.mark.parametrize('arg0', [1, 2, 3])  # 多装饰器 笛卡尔积的效果 两两相乘
@pytest.mark.parametrize('arg1', [4, 5, 6])
def test_a01_1(arg0, arg1):
    print(f'arg0 is {
      
      arg0},arg1 is {
      
      arg1}')


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

The role of the ids parameter

import pytest


def login(username, password):
    data = {
    
    'allen': '12', 'smith': '34', 'ford': '56'}
    if data.get(username) == password:
        return 'success'
    else:
        return 'failed'


@pytest.mark.parametrize('username, password, expect', [('allen', '12', 'success'), ('smith', '344', 'failed')],
                         ids=['login success', 'login failed'])
def test_a01_1(username, password, expect):
    assert login(username, password) == expect


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

9. setup and teardown (not commonly used, there are better ones)

  • Setup often refers to the configuration part (preconditions) in the test case, and teardown corresponds to the destruction part (environment demolition)

  • PyTest supports xUnit style structure, setup() and teardown() methods are used to initialize and clean up the test environment, which can ensure the independence of test cases

method scope illustrate
setup_function/teardown_function function function Each function is used once (the function and method in the class are not counted)
setup_class/teardown_class class class Need to be defined in the class, a class runs once
setup_module/teardown_function module (a py file) run a module once
setup_method/teardown_method method (function in class) one method run once
setup/teardown method (function in class) one method run once
import pytest


def setup_function():
    print('\n函数前执行 setup')

    
def teardown_function():
    print('\n函数后执行 teardown')


def test_a01_1():
    pass


def test_a01_2():
    pass


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

import pytest


class Test_all():
    def setup_class(self):
        print('\n方法前执行 setup')

    def teardown_class(self):
        print('\n方法后执行 teardown')

    def test_a01_1(self):  # method 方法不叫函数
        pass

    def test_a01_2(self):
        pass


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

import pytest


def test_a01_3():
    pass


def setup_module():
    print('\n模块前执行 setup')


def teardown_module():
    print('\n模块后执行 teardown')


class Test_all():
    def test_a01_1(self):  # method 方法不叫函数
        pass

    def test_a01_2(self):
        pass


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

insert image description here

import pytest


class Test_all():
    def setup_method(self):
        print('\n方法前执行 setup01')

    def teardown_method(self):
        print('\n方法后执行 teardown01')

    def setup(self):
        print('\n方法前执行 setup02')

    def teardown(self):
        print('\n方法后执行 teardown02')

    def test_a01_1(self):  # method 方法不叫函数
        pass

    def test_a01_2(self):
        pass


if __name__ == '__main__':
    pytest.main(['-sv', __file__])

10. pytest-base-url plugin

import pytest, requests


def test_a01_1(base_url):  # 当作为fixture使用的时候是base_url,安装的是pytest-base-url
    resp = requests.get(base_url)
    assert resp.status_code == 200


if __name__ == '__main__':
    pytest.main(['-sv', '--base-url', 'https://www.baidu.com', __file__])
    # pytest.main(['-sv', __file__])  # 使用配置文件执行,本级目录下新建pytest.init文件,新增一行 base_url = https://www.baidu.com

insert image description here

11. pytest-repeat plugin

import pytest


@pytest.mark.repeat(3)
def test_a01_1():
    print('01 testing')
    assert 1 == 1


if __name__ == '__main__':
    pytest.main(['-sv', __file__])
import pytest


def test_a01_1():
    print('01 testing')
    assert 1 == 1


if __name__ == '__main__':
    pytest.main(['-sv','--count=3', __file__])

insert image description here

import pytest


def test_a01_A1():
    print('A1 testing')
    assert True


def test_a01_A2():
    print('A2 testing')
    assert True


def test_a01_B1():
    print('B1 testing')
    assert True


def test_a01_B2():
    print('B2 testing')
    assert True


if __name__ == '__main__':
    pytest.main(['-sv', '--count=2', '--repeat-scope=session', __file__])  # session/module/class都是1212的顺序

insert image description here

12. Allure generates reports

Guess you like

Origin blog.csdn.net/qq_45138120/article/details/126701528