10z Python编程语言与测试框架 - 软件测试

软件测试所有内容笔记正在陆续更新中,笔记已经在本地记录,全部为自己手动记录的笔记及总结,正在开始更新中,后续会逐步更新并完善到 软件测试学习内容总结 专栏。
本节内容为:Python编程语言与测试框架

文章目录

  • 1. python pytest测试实战 1
        • pytest 介绍与安装
        • pytest 运行
        • pytest 框架结构
        • pytest 参数化
  • 2. python pytest测试实战 2
        • 1. pytest fixture 高级用法
        • 2. conftest.py 用法
        • 3. pytest 配置 — `pytest.ini`
        • 4. pytest 常用插件
        • 5. allure 生成测试报告
  • 3. python pytest 插件开发
        • 6. pytest hook 函数

1. python pytest测试实战 1

课程价值
理解 pytest 框架结构
掌握运行及常用的运行参数
掌握参数化与数据驱动

大纲
pytest 介绍与安装
pytest 常用执行参数
pytest 框架结构
pytest 参数化与数据驱动

pytest 介绍与安装

pytest 介绍

  • 单元测试,代码测试
    • 构面web,app,接口以pytest为基础,所有自动化课程都在用pytest
    • python界比较主流的单元测试框架,unittest,pytest,nose…
    • 入门难度低,第三方库丰富性,通用性,与allure生成的报告非常的美观

pytest 安装

  • pytest 官网:http://www.pytest.org
  • 安装
    • pip install pytest
    • Pycharm pytest 配置
  • 版本验证
    • pytest --version

Pycharm 配置

  1. 进入 pycharm 设置

  2. 搜索 pytest

  3. 设置 test runner
    10z Python编程语言与测试框架 - 软件测试_第1张图片

  4. 删除 pycharm 运行记录
    在这里插入图片描述

pytest 运行

编写用例

  • 编写计算机代码
  • 编写一条计算机【相加】功能的测试用例

calc.py文件

# 计算器 
class Calculator:
    # 加法
    def add(self, a, b):
        return a + b
    # 减法
    def sub(self, a, b):
        return a - b
    # 乘法
    def mul(self, a, b):
        return a * b
    # 除法
    def div(self, a, b):
        return a / b

test_calc.py 文件

#  python_pytest包名
from python_pytest.calc import Calculator
class TestCalc:
    def test_add(self):
        # 实例化计算器类
        calc = Calculator()
        # 调用 add 方法
        result = self.calc.add(1, 1)
        # 得到结果之后,要有断言
        assert result == 2

pytest 规则

  • 测试文件、测试函数、测试方法,名称需要以 test_ 开头
  • 测试类名称需要 Test 开头
  • 测试类中不能包含 init 方法

pytest 运行方式

  1. Pycharm 界面运行
    • 运行整个测试文件:在文件上点击鼠标右键,选择 run
    • 点击绿色小三角,运行对应的测试类或者测试方法
  2. 命令行方式运行
    • 运行当前目录下所有测试文件:pytest
    • 运行指定的测试文件:pytest 文件名
    • 运行指定文件中的指定的类或者方法:pytest 文件名::测试类名::测试方法名
    • 查看执行过程中的详细信息和打印信息:pytest -vs
    • 只收集测试用例不运行:pytest --collect-only
    • 生成执行结果文件:pytest --junitxml=./result.xml

测试用例的识别与运行

  • pytest
  • pytest -v (最高级别信息 --verbose) 打印详细运行日志信息
  • pytest -v -s 文件名 (s是带控制台输出结果,也是输出详细)-s打印print的内容
  • pytest 文件名.py ( 执行单独一个pytest模块)
  • pytest 文件名.py::类名 (运行某个模块里面某个类)
  • pytest 文件名.py::类名::文件名 (运行某个模块里面某个类里面的方法)

测试用例常用参数

  • pytest -x 文件名 (一旦运行报错,就停止运行)
  • pytest - -maxfail=[num] (当运行错误达到num的时候就停止运行)
  • pytest -k “类名 and not 方法名” (执行某个关键字的用例)
  • pytest -m [标记名] @pytest.mark.[标记名] (将运行有这个标记的测试用例)

常用的执行参数

  • pytest --collect-only (只收集用例)
  • pytest --junitxml=./result.xml (生成执行结果文件)
  • pytest --setup-show (回溯 fixture 的执行过程)
  • 更多的用法使用 pytest --help 查看帮助文档

test_a 函数名、TestCalc 类名、test_add 方法名
pytest test_calc.py::TestCalc -vs
pytest test_calc.py::TestCalc::test_add -vs
pytest test_calc.py::test_a -vs
pytest --collect-only
pytest test_calc.py --junitxml=./result.xml


pytest 框架结构
  • 模块级 (setup_module / teardown_module) 模块始末,全局的(优先最高
  • 函数级 (setup_function / teardown_function) 只对函数用例生效(不在类中)
  • 类级 (setup_class / teardown_class) 只在类中前后运行一次(在类中)
  • 方法级 (setup_method / teardown_methond) 开始于方法始末(在类中)
  • 类里面的(setup / teardown)运行在调用方法的前后

setup / teardown默认为方法级别,setup_method / teardown_methond

Unittest:https://docs.python.org/3/library/unittest.html
test fixture:测试装置; -做准备工作,数据准备,清理的工作,测试用例之前和测试用例之后要做的事
test case:测试用例
test suite:测试套件,将测试用例组装起来
test runner:测试执行器,用来执行测试用例
类似于setup、teardown

def setup_module(self):
    print('模块级别 setup')
def teardown_module(self):
    print('模块级别的 teardown')

def setup_function(self):
    print('函数级别 setup')
def teardown_function(self):
    print('函数级别的 teardown')

class TestDemo:
    def setup_class(self):
        print('类级别 setup')
    def teardown_class(self):
        print('类级别的 teardown')

    def setup(self):
        print('方法级别 setup')
    def teardown(self):
        print('方法级别的 teardown')

    def test_demo1(self):
        print('test_demo1')
    def test_demo2(self):
        print('test_demo2')

class TestDemo1:
   def setup(self):
        print('方法级别 setup')
    def teardown(self):
        print('方法级别的 teardown')
        
    def test_demo1(self): 
        print('test_demo1')

test_calc.py 改造

from python_pytest.calc import Calculator
class TestCalc():
    def setup_class(self):
        print('开始计算')
        # 实例化计算器类
        self.calc = Calculator()
    def teardown_class(self):
        print('计算结束')
    
    def test_add(self):
        result = self.calc.add(1, 1)
        assert result == 2

★★★★★

self.calc = Calculator()
在setup方法中创建实例calc,但实例是局部变量,别的方法调用不到,calc的作用域只限制在setup这个方法中,所以其他的方法想要调用setup方法中的这个实例的话,要改变它的作用域,把它的作用域变得更大一些,在calc前面加上self.,把calc变为实例变量

pytest 参数化

参数化与数据驱动

  • 参数化?
    • 待测试的输入和输出是一组数据,可以把测试数据组织起来,用不同的测试数据调用相同的测试方法
  • 数据驱动?
    • 数据驱动就是数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。说的直白些,就是参数化的应用

  • 参数化
    • 单个参数化:参数名称写在字符串中,参数值用列表传递
    • 多个参数:参数名称写在字符串中,参数值用列表套列表或者元组的方式传递 eg:@pytest.mark.parametrize('a, b, expect', [(1,1,2)])
    • 测试用例起别名:ids=[ ]
    • 笛卡尔积:用两个装饰器分别传入参数
    • 从 yaml 中读取参数:数据读取成为参数化中需要的参数格式

pytest 参数化

  • 参数化装饰函数
  • ids 参数增加可读性

mark.parametrize 参数化

  • 场景:
    • 测试数据是传入的,测试的预期结果也是传入的,二个不同的参数一一对应,输入的数据经过调用执行后结果是否与预期一致
  • 解决:
    • 使用 mark 中的 @pytest.mark.parametrize 进行参数化和数据驱动更灵活
  • 应用:
    1. 方法,类上加上装饰器都可以
    2. 另外组合方式可以实现更多测试用例的自动生成

判断result是浮点数,并处理
if isinstance(result,float):
result = round(result,2)

class TestCalc():
    def setup_class(self):
        print('开始计算')
        # 实例化计算器类
        self.calc = Calculator()
    def teardown_class(self):
        print('计算结束')

    @pytest.mark.parametrize('a, b, expect', [
            (1,1,2), (0.1,0.1,0.2), (-1,-1,-2), (0.1,0.2,0.3)
        ], ids=['int','float','negative','round'])
    def test_add(self, a, b, expect):
        # 调用 add 方法
        result = self.calc.add(a, b)
        # 判断result是浮点数,并处理
        if isinstance(result, float):
            result = round(result, 2)
        # 得到结果之后,要有断言
        assert result == expect

用yaml文件实现
calc.yaml文件

add:
  datas:
    -
      - 1
      - 1
      - 2
    - - 100
      - 100
      - 200
    - [0.1,0.2,0.3]
    - [0.1,-0.2,0.3]
    - [-1,-1,-2]
  myid:
    - 'int'
    - 'bigint'
    - 'float'
    #    - 'round'
    - 'fail'
    - 'negative'

test_calc.py

import yaml
import pytest
from python_pytest.calc import Calculator
with open('./datas/calc.yaml') as f:
    datas = yaml.safe_load(f)['add']
    add_datas = datas['datas']
    print(add_datas)
    myid = datas['myid']
    print(myid)

class TestCalc():
    def setup_class(self):
        print('开始计算')
        self.calc = Calculator()
    def teardown_class(self):
        print('计算结束')
        
    @pytest.mark.parametrize('a, b, expect', add_datas, ids=myid)
    def test_add(self, a, b, expect):
        result = self.calc.add(a, b)
        if isinstance(result, float):
            result = round(result, 2)
        assert result == expect

笛卡尔积:用两个装饰器分别传入参数
a的取值和b的取值组合的情况
a有10种可能,b有10种可能,a b组合的情况

import pytest
@pytest.mark.parametrize('a', [1, 2, 3])
@pytest.mark.parametrize('b', [4, 5, 6])
def test_param(a, b):
    print(f'a = {a}, b = {b}')

作业

  1. 补全计算器中加法和除法的测试用例
  2. 使用参数化完成测试用例的自动生成
  3. 在调用测试方法之前打印【开始计算】,在调用测试方法之后打印【计算结束】
  • 注意:
    • 使用等价类,边界值,因果图等设计测试用例
    • 测试用例中添加断言,验证结果
    • 灵活使用 setup(), teardown() , setup_class(), teardown_class()

代码 https://github.com/ceshiren/HogwartsFIS03

2. python pytest测试实战 2

课程价值
掌握 pytest fixture 用法
掌握 pytest 常用插件
掌握 allure
了解 pytest hook 函数

大纲
pytest fixture 高级用法
conftest.py 用法
pytest 配置
pytest 常用插件
allure 生成测试报告
pytest hook 函数

allure 下载: https://repo1.maven.org/maven2/io/qameta/allure/allure-commandline/2.13.7/
hook 函数:https://docs.pytest.org/en/latest/_modules/_pytest/hookspec.htm

1. pytest fixture 高级用法

定义

@pytest.fixture() 
def fixture_method(): 
        print("setup 操作") 
        yield 
        print("teardown 操作")

调用方式

  • 测试用例中传入 fixture方法名
  • @pytest.mark.usefixtures("fixture方法名")
  • 自动调用 @pytest.fixture(autouse=True) #默认为False,不推荐使用

fixture 作用域

  • function 函数或者方法级别都会被调用
  • class 类级别调用一次
  • module 模块级别调用一次 #python文件
  • session 是多个文件调用一次 #pytest执行一次测试的整个过程

package 新开放的功能
通过scope来使用


  • 控制方法:@pytest.fixture(scope="")
  • scope 的取值
    • function 默认值
    • class
    • module
    • session

@pytest.fixture(scope=‘function’)

test_scope文件

import pytest
@pytest.fixture(scope='module')  # function class module session
def connectdB():
    print('连接数据库操作')
    yield
    print('断开数据库连接')

class TestDemo:
    def test_a(self, connectdB):
        print('测试用例a')
    def test_b(self, connectdB):
        print('测试用例b')

class TestDemo1():
    def test_a(self, connectdB):
        print('测试用例a')
    def test_b(self, connectdB):
        print('测试用例b')

fixture 方法返回值获取

  • 把返回值写到 fixture方法 的 yield 后面
  • 在测试用例中使用 fixture方法名获取返回值
    #直接print fixture方法名获得fixture的返回值

fixture 的作用

  • 定义传入测试中的数据集
  • 配置测试前系统的初始状态
  • 为批量测试提供数据源等

fixture 的用法

  1. 类似 setup, teardown 功能,但比 setup, teardown 更灵活
  2. 直接通过函数名字调用或使用装饰器 @pytest.mark.usefixtures('test1')
  3. 允许使用多个 fixture
  4. 使用 autouse 自动应用,如果要返回值,需要传 fixture 函数名
  5. 作用域(session > module > class > function)
  • 场景一:自动化应用
    • 测试用例执行时,有的用例需要登录才能执行,有些用例不需要登录
    • setup 和 teardown 无法满足
import pytest
@pytest.fixture()  
def login():
    print('登录操作')
# 提前登录    传入fixture方法名login
def test_case1(login):
    print('测试用例1')
def test_case2():
    print('测试用例2')
# 提前登录   写装饰器的方式进行调用
@pytest.mark.usefixtures('login')
def test_case4():
    print('测试用例4')
  • 场景二:yield
    • 你已经可以将测试方法前要执行的或依赖的解决了
    • 测试方法后销毁清除数据的要如何进行呢?
@pytest.fixture()
def login():
    print('登录操作')
    yield 
    print('登出操作')

生成器示例
#在生成器中想拿到里面的内容,必须调用next()方法

# yield 生成器
def provider():
    # 循环读取
    for i in range(10):
        print('开始操作')
        # 相当于 return i,记录上一次执行的位置
        yield i
        print('结束操作')
p = provider()
# 打印的对象类型就是生成器 generator
# 在生成器中想拿到里面的内容,必须调用next()方法
# print(p)
# print(next(p))
# print(next(p))
for i in p:
    print(i)

test_fixture.py 文件

import pytest
# 创建登录的fixture 方法
@pytest.fixture()
def login():
    print('登录操作')
    username = 'chan'
    password = '123'
    token = 'token123'
    yield [username, password, token]
    print('登出操作')

# 提前登录
def test_case1(login):
    # 通过fixture方法的名称,相当于调用了这个方法,可以拿到返回的值
    print(f'login information: {login}')
    print('测试用例1')

pytest --setup-show test_fixture.py -vs
yield 关键字激活了fixture中teardown的操作。
yield 把方法分为上下两部分,上面的所有操作属于setup操作,下面的所有操作属于teardown操作

有teardown的操作,就用yield返回数据,如果没有teardown操作,就把yield换成return,yield 和return都可以返回数据

生成器(generator)
只要一个方法中有yield关键字,就是一个生成器
生成器一次只能拿一个值
next() 方法拿到后面的数,一个一个往后拿
yield i 相当于return i,记录上一次执行的位置

需要fixture返回数据时,可以直接在方法体中通过使用fixture方法的名字,调用它返回的数据

  • 场景三:autouse
    • 不想让原测试方法有任何改动
    • 全部都需要使用 fixture 方法,没特例

@pytest.fixture(autouse=True) # 自动调用,默认为False
和setup、teardown一样了,不推荐使用,简单了解

import pytest
@pytest.fixture(autouse=True)
def login():
    print('登录操作')
# 提前登录  不许用传fixture 自动调用
def test_case1():
    print('测试用例1')
2. conftest.py 用法

conftest.py文件中有打开文件的操作时,如果报编码错误,在open中添加encoding=‘utf-8’
with open(yaml_file_path, encoding=‘utf-8’) as f:

应用场景

  • 与其他测试工程师合作一起开发时,大家需要用到相同的功能
  • 把公共模块放到大家方便调用的文件中

conftest.py 用法

  • conftest.py 文件名是不能改变
  • conftest.py 与运行的用例要在同一个 package 下(是包不是文件夹
  • 不需要 import 导入 conftest.py ,pytest 用例会自动查找
  • 所有同目录测试文件运行前都会执行 conftest.py 文件
  • 全局的配置前期工作都可以写在这里

pytest -vs test_fixture.py test_scope.py
conftest.py 生效遵循就近原则,离的最近的生效。如果当前文件中有相同名称的fixture方法,则调用当前文件中的。如果没有则调用同一个包中conftest中的fixture方法。同包中没有则调用外层包中的conftest中的fixture方法。
优先调用同级目录下的conftest方法。

所有文件优先调用最外面的conftest.py
conftest.py文件所在包中的所有文件和包都会执行pytest.py文件,conftest.py有问题,所有的文件都会报错。

conftest.py 文件

import pytest
import yaml
import os
from python_pytest.calc import Calculator
# 要使用绝对路径打开yaml文件,conftest.py文件所在包中的所有文件和包都会执行pytest.py文件,conftest.py有问题,所有的文件都会报错。
# os.path.dirname(__file__)获取当前文件conftest.py所在的路径
yaml_file_path = os.path.dirname(__file__) + '/datas/calc.yaml'

with open(yaml_file_path, encoding='utf-8') as f:
    datas = yaml.safe_load(f)['add']
    add_datas = datas['datas']
    print(add_datas)
    myid = datas['myid']
    print(myid)

@pytest.fixture(params=add_datas, ids=myid)
def get_add_datas(request):
    print('开始计算')
    data = request.param
    print(f'request.param 里面的测试数据:{data}')
    yield data
    print('结束计算')

@pytest.fixture(scope='session')
def connectdB():
    print('连接数据库操作')
    yield
    print('断开数据库连接')

@pytest.fixture(scope='class')
def get_calc():
    print('获取计算器实例')
    calc = Calculator()
    return calc

test_calc.py文件

import yaml
import pytest
from python_pytest.calc import Calculator
class TestCalc():
    # @pytest.mark.parametrize('a, b, expect', add_datas, ids=myid)
    def test_add(self, get_calc, get_add_datas):
        result = None
        try:
            # 调用 add 方法
            result = get_calc.add(get_add_datas[0], get_add_datas[1])
            # 判断result是浮点数,并处理
            if isinstance(result, float):
                result = round(result, 2)
        except Exception as e:
            print(e)
        assert result == get_add_datas[2]

calc.yml

add:
  datas:
    - [1,1,2]
    - [100,100,200]
    - [0.1,0.2,0.3]
    - [0.1,-0.2,-0.1]
    - [-1,-1,-2]
    - [' ', 5, '请输入数字']
  myid:
    - 'int'
    - 'bigint'
    - 'float'
    - 'fail'
    - 'negative'
    - '空格'

场景:fixture 带参数传递

fixture通过params=[]来传递参数,ids=""来传递别名
使用fixture传递参数,要拿到params里面的数据,需要在fixture方法中传递参数request
使用request.param获取params传入的值,得到的值为列表的形式

import pytest
@pytest.fixture(params=[1, 2, 3])
def login1(request):
    data = request.param
    print('获取测试用例')
    return data

def test_case1(login1):
    print(login1)
    print('测试用例1')

相关练习:testing文件夹中的test_param.py,calc.yaml, conftest.py, test_calc.py文件

3. pytest 配置 — pytest.ini

在使用pytest.ini配置文件时,执行测试用例报gbk编码的错误。首先选中pytest.ini文件,然后点击上方的File—File Encoding—GBK—弹出对话框点击Convert(转换)
报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa1 in position 70: illegal multibyte sequence

规则

  • 写在 pytest.ini 文件中
  • pytest 的主配置文件,一般放在项目工程的根目录
  • 指定 pytest 的运行方式
  • 不能使用任何中文符号

pytest 配置文件

[pytest]
markers 自定义mark标签名
addopts 运行时的参数(可添加多个命令行参数,空格分隔,所有参数与命令行一致)
python_files 自定义测试文件命名规则
python_classes = Test* 自定义测试类命名规则
python_functions = test_* check_* 自定义测试方法命名规则
testpaths = bilibili baidu 指定特定路径运行
norecursedirs = result logs datas test_demo* 运行时忽略某些文件夹

pytest.ini 文件(文件名固定)

[pytest] 
markers = add 
                   div 
                   sub 
                   mul

;运行时的参数 
addopts = -vs 

;自定义测试文件命名规则 
python_files = check_* test_* 
;自定义测试类命名规则 
python_classes = Check* Test* 
;自定义测试方法命名规则 
python_functions= test_* check_* 

; 指定执行路径 
testpaths = sub_demo 
; 忽略路径 
norecursedirs = datas

mark参数代码

class TestCalc():
    @pytest.mark.div
    def test_div(self):
        print('test_div')

pytest test_calc.py -vs -k add
首先要在pytest.ini文件的markers中定义相关的mark标记,然后使用-k参数运行

check_demo.py文件

def check_demo():
    print('check_demo')

class CheckDemo:
    def check_a(self):
        print('check_a')

python_files = check_* test_*
python_classes = Check* Test*
python_functions= test_* check_*

4. pytest 常用插件

Windows的Pycharm在界面安装的插件在命令行不起作用,命令行使用的插件为系统配置路径中的插件,所以想在pycharm命令行执行命令,必须要在环境变量中安装插件

pytest 工作中常用的插件
https://pypi.org/

  • pip install pytest-rerunfailures 失败重跑
  • pip install pytest-assume 多重较验
  • pip install pytest-ordering 控制用例的执行顺序
  • pip install pytest-xdist 分布式并发执行测试用例
  • pip install pytest-html 测试报告
  • pip install pytest-sugar 命令行显示美化

pytest-rerunfailures

运行环境要求Python版本在3.5-3.8之间 (pypi中可以查看)

  • 场景:
    • 测试失败后要重新运行 n 次,要在重新运行之间添加延迟时间,间隔 n 秒再运行。
  • 安装:
    • pip install pytest-rerunfailures
  • 执行:
    • pytest -vs --reruns 3 test_class.py
    • pytest -vs --reruns 5 --reruns-delay 1
    • @pytest.mark.flaky(reruns=5,reruns_delay=2)指定某个用例

–reruns 设置重跑次数
–reruns-delay 设置每次重跑之间的间隔时间

from time import sleep
import pytest
def test_rerun():
    sleep(0.5)
    assert 1 == 2
def test_rerun1():
    sleep(0.5)
    assert 2 == 2

@pytest.mark.flaky(reruns=4, reruns_delay=1)
def test_rerun2():
    sleep(0.5)
    assert 3 == 2

pytest test_rerun.py --reruns 3 --reruns-delay 1 所有测试用例都会失败重跑
在测试用例中加入装饰器时,直接使用pytest test_rerun.py运行,加了装饰器的测试用例才会失败重跑

pytest-assume

  • 场景:
    • 一个方法中写多条断言,中间有1条失败,后面的代码就不执行了。
    • 我们希望有失败也能执行完毕
  • 安装:
    • pip install pytest-assume
  • 执行:
    • pytest.assume(1==4)
    • pytest.assume(2==4)
import pytest
def test_a():
    # assert 1 == 1
    # assert False == True
    # assert 100 == 200
    pytest.assume(1 == 1)
    pytest.assume(False == True)
    pytest.assume(100 == 200)
    pytest.assume(300 == 1)

pytest test_assume

pytest-ordering

  • 场景:
    • 对于集成测试,经常会有上下文依赖关系的测试用例
  • 安装:
    • pip install pytest-ordering
  • 执行:
    • @pytest.mark.run(order=2)

case 基本设计原则

  • 不要让 case 有顺序
  • 不要让测试用例有依赖
  • 如果你无法做到,可以临时性的用插件解决
import pytest
# @pytest.mark.last
@pytest.mark.run(order=2)
def test_foo():
    assert True

# @pytest.mark.first
@pytest.mark.run(order=1)
def test_bar():
    assert True

pytest-xdist

  • 场景:
    • 测试用例数量庞大,执行需要时间太长
  • 安装:
    • pip install pytest-xdist
  • 执行:
    • pytest -n 3

分布式执行测试用例原则
10z Python编程语言与测试框架 - 软件测试_第2张图片

pytest test_ordering.py
pytest test_ordering.py -n 3

pytest-html

  • 安装:
    • pip install pytest-html
  • 生成 html 报告
    • pytest -vs --html=report.html --self-contained-html

pytest-sugar

  • 安装
    • pip install pytest-sugar

使命令行的log日志更加好看,展示进度,显示对勾

5. allure 生成测试报告

allure 安装

  • https://mvnrepository.com/artifact/io.qameta.allure/allure-commandline
  • 本地工具安装:下载zip包,解压zip包,把 bin 目录配置到环境变量
  • 安装 pytest 插件:pip install allure-pytest

allure 用法

  • 生成 allure 测试结果: pytest —alluredir=./result
  • 展示报告:allure serve ./result
  • 生成最终版本的报告:allure generate ./result
  • 清除上一次的记录:allure generate result -o result/html --clean result/html
  • 打开报告:allure open -h 127.0.0.1 -p 8883 ./result/

-o 指定存放生成结果的文件夹,–clean 清空文件夹
pytest --alluredir test_calc.py ./result
allure generate result -o result/html --clean result/html
allure open -h 127.0.0.1 -p 8883 ./result/html

3. python pytest 插件开发

6. pytest hook 函数

pytest 插件加载方式

  • 内置 plugin
  • 外部插件:第三方插件
  • 自定义插件:conftest.py 存放的本地插件

自定义插件

  • hook(钩子)函数定制和扩展插件
  • 官网:https://docs.pytest.org/en/latest/_modules/_pytest/hookspec.html
  • conftest.py:本地的插件库,存放 fixture 函数或者 hook 函数作用于该文件所在的目录及其所有的子目录

编写自己的插件

  • pytest_collection_modifyitems 收集上来的测试用例实现定制化功能
  • 解决问题:
    • 自定义用例的执行顺序
    • 解决编码问题(中文的测试用例名称)
    • 自动添加标签

  • hook 函数定义在 conftest.py 文件中
  • pytest_collection_modifyitems 收集上来的测试用例实现定制化功能


for item in items:
    

pytest test_hook.py -m add
pytest test_hook.py -k add

items 所有测试用例组成的列表
item.nodeid 拿到测试用例名称


课后作业

  1. 补全计算器(加减乘除)的测试用例
  2. 使用数据的数据驱动,完成加减乘除用例的自动生成
  3. 创建 fixture 方法实现执行测试用例前打印【开始计算】,执行测试用例之后打印【计算结束】
  4. 控制测试用例顺序按照【加-减-乘-除】这个顺序执行
  5. 结合allure 生成测试结果报告

你可能感兴趣的:(软件测试学习内容总结,软件测试,编程语言,python)