【Python自动化训练营】pytest实战(二)课程贴

预习贴

参考链接

https://pytest-ordering.readthedocs.io/en/develop/
https://github.com/ftobia/pytest-ordering/blob/develop/pytest_ordering/init.py
https://pytest-dependency.readthedocs.io/en/stable/usage.html
https://docs.pytest.org/en/latest/fixture.html#fixture
http://allure.qatools.ru/

上节课作业

类变量 实例变量
类方法,实例方法区别

异常情况需要考虑,比如除数据为0,可以通过 try,except 或者是 pytest.raise 来捕获异常

pytest 定义执行顺序

unittest 执行顺序,ASCII 顺序执行
pytest 执行顺序, 用例的编写顺序

单元测试的原则:单元测试不允许测试用例有顺序,测试用例要保持独立 ,不要影响其它测试用例。
集成测试: 也要按照上面的规则, 但是会有用例之间相互依赖的情况 ,就需要定义用例的顺序,

  • pytest-ordering ,修改conftest.py 文件里的 下面的方法,来完成 自定义执行顺序。 也可以自动的添加一些标签,执行的时候来指定某一类测试用例
def pytest_collection_modifyitems(session, config, items:list):
    # print(items)
    # print(type(items))
    # items.reverse()
    for item in items:
        print(item.nodeid)
        if 'add' in item.nodeid:
            item.add_marker(pytest.mark.add)

        if 'sub' in item.nodeid:
            item.add_marker(pytest.mark.sub)

pytest.ini 文件
可以修改测试文件,测试类,测试方法名的定义规则
可以指定后面的参数
也可以指定 markers 标签

在执行的目录下,定义pytest.ini文件

例如:

[pytest]

markers = add
          sub
          div
          mul

;python_files
python_classes = Hello*
python_functions = select_* test_*
addopts = -vs --aluredir ./result

pytest 用例依赖关系

pytest-dependency

pytest 自动添加标签

测试步骤的数据驱动

pytest fixture 高级用法

yield 生成器:

  • 相当于 return i
  • 暂时操作
  • 并且记住上一次的执行位置

Allure

安装 allure ,

安装 allure-pytest

pip install allure-pytest

执行pytest 生成中间结果

pytest test_calc.py --alluredir ./result/

生成allure 最终的测试报告

allure generate ./result/

课间练习与课后作业

课间练习

  • 使用测试数据的数据驱动(参数化)完成加法和除法
  • 修改运算规则 , pytest.ini 文件(只识别add_ div_开头的方法)
  • 自动添加mark 标签, 只运行 add 开头的方法

课后作业

import yaml
from func.Calc import Calc
import pytest
class TestDemo():
    def setup(self):
        self.calc = Calc()

    def getsteps(self,a,b,c,a1,b1,c1):
        self.getyaml = yaml.safe_load(open("./test_config.yaml"))
        for i in self.getyaml:
            if 'add' == i:
                assert self.calc.add(a,b) == c
            elif 'div' == i:
                assert self.calc.div(a1,b1) == c1

    @pytest.mark.parametrize(("a","b","c"),yaml.safe_load(open("./add_normal_data.yaml")))
    @pytest.mark.parametrize(("a1","b1","c1"),yaml.safe_load(open("./div_normal_data.yaml")))
    def add_mix(self,a,b,c,a1,b1,c1):
        self.getsteps(a,b,c,a1,b1,c1)

ini文件内容:

第三题待续

课间练习

使用测试数据的数据驱动(参数化)完成加法和除法

import pytest
import yaml

from python_code.calc import Calc


def get_data():
    test_data = yaml.safe_load(open("./test_data.yml"))
    return test_data


def get_steps():
    with open('./test_steps.yml') as f:
        return yaml.safe_load(f)


class TestCalc:
    def setup_class(self):
        print("Test start!")
        self.calc = Calc()

    def teardown_class(self):
        print("\nTest finished!")

    @pytest.mark.parametrize('a,b,result', get_data()["add"])
    @pytest.mark.parametrize('steps', get_steps()["add"])
    # @pytest.mark.run(order=3)
    def test_add(self, a, b, result,steps):
        # assert self.calc.add(a, b) == result
        self.add_steps(a, b, result,steps)

    def add_steps(self, a, b, result, steps):
        for step in steps:
            if 'add' == step:
                print(f"step is {step}")
                assert self.calc.add(a, b) == result
            else:
                raise NameError


    @pytest.mark.parametrize('a,b,result', get_data()["div"])
    @pytest.mark.parametrize('steps',get_steps()["div"])
    # @pytest.mark.run(order=1)
    def test_div(self, a, b, result,steps):
        # assert self.calc.div(a, b) == result
        self.div_steps(a, b, result,steps)

    def div_steps(self, a, b, result, steps):
        for step in steps:
            if 'div' == step:
                print(f"step is {step}")
                assert self.calc.div(a, b) == result
            else:
                raise NameError


if __name__ == '__main__':
    pytest.main()

修改运算规则 , pytest.ini 文件(只识别add_ div_开头的方法)

# 修改pytest.ini 文件如下
[pytest]

python_functions = add_* div_*

自动添加mark 标签, 只运行 add 开头的方法

# 修改pytest.ini文件自动添加标签
[pytest]

markers = add
# 或修改conftest.py 文件如下
import pytest


def pytest_collection_modifyitems(session, config, items:list):
    for item in items:
        print(item.nodeid)
        if 'add' in item.nodeid:
            item.add_marker(pytest.mark.add)
# 执行使用 pytest -m add 命令
关闭