Pytest测试框架学习

一、安装pytest

1、pip install pytest  -i https://pypi.duoban.com/simple

二、pytest编写测试用例的规则

1、测试文件命名规则

文件命名为test_*.py或者*_test.py

2、测试用例规则

编写测试用例的两种方式

纯函数方式编写测试用例,以test_命名的函数

def test_login_success():
    resp = login(userName="123",password="456")
    #断言,断言就是判断结果是否正确的过程
    #断言接口响应状态码
    status_code = resp.status_code
    assert status_code == 200
    #针对接口响应字段的核心数据做断言,code码
    code = resp.json()["code"]
    assert code == "0"
    message = resp.json()["message"]
    assert message == "success"
    text = resp.text
    assert text == '{"code":"0","message":"success","data":null}'

以类的方式编写测试用例,不能包含init方法,以test开头的方法代表一条用例

class TestBuyerLogin:
    def test_login_seccess(self):
        resp = buyer_login()
        assert resp.json()["username"] == "123"
        assert resp.json()["nickname"] == "123"

3、测试用例执行

右键执行,pycharm默认是以unittests的方式执行,需要修改执行方式,然后把之前的执行记录清除,然后就可以右键执行,查看所有用例的执行结果,需要勾选控制台上的对号

Pytest测试框架学习_第1张图片Pytest测试框架学习_第2张图片

命令行执行

pytest -sv 文件路径::测试类::测试方法,sv表示有详细的执行日志

pytest -sv pytest_study/test_123.py::Test123::test_123

4、pytest参数化

当用例处理测试数据和期望结果不同,其他代码都高度相似时,我们可以使用参数化的方式优化用例编写

首先整理数据

使用装饰器引入数据

编写测试用例,传入测试数据

test_data = [
    ['1234','123456','0','success','{"code":"0","message":"success","data":null}'],
    ['',        '123456','1','参数为空','{"code":"1","message":"参数为空","data":null}'],
    ['dawei123','',       '1','参数为空','{"code":"1","message":"参数为空","data":null}']
]
@pytest.mark.parametrize('username,password,expect_code,expect_message,expect_body',test_data)
def test_login(username,password,expect_code,expect_message,expect_body):
    resp = login(userName=username,password=password)
    status_code = resp.status_code
    assert status_code==200
    code=resp.json()["code"]
    assert code==expect_code
    message=resp.json()["message"]
    assert message==expect_message
    text=resp.text
    assert text==expect_body

5、pytest笛卡尔积参数化

适用于接口中有多个参数,具备多组有效值,需要进行组合

一个用例有多个装饰器,会拿两个装饰器的乘积

A= ["A1","A2","A3","A4"]
B= ["B1","B2"]
@pytest.mark.parametrize("A",A)
@pytest.mark.parametrize("B",B)
def test_create_trade(self,A,B):
    buyer_login()
    if B== "B1":
        buy_now()
    elif B== "B2":
        add_cart()
    resp = create_trade(A=A,B=B)
    assert resp.status_code == 200

6、前置后置处理器

特殊函数:setup和teardown

模块级别:setup_module、trardown_module

setup_module:在每个模块执行前执行 

teardown_module:在每个模块执行后执行

一个pytest文件就可以理解为一个模块

函数级别:seupt_function,teardown_function

不在类中的方法

setup_function:在每个用例执行前执行

teardown:在每个用例执行后执行

类级别:setup_class,teardown_class

setup_class:当前类下所有用例执行前执行

teardown_class:当前类下执行后执行

class A():

    def setup_class(self):

    def teardown(self):

方法级别:setup_method,teardown_method

setup_method:类下的每个测试用例执行前都会执行

teardown_method:类下的每个测试用例执行后都会执行

7、pytest fixture函数

一种特殊函数,可以实现前置和后置处理

@pytest.fixture(scope="function",autouse=True)

def buyer_login_fixtyre():

buyer_login()

print("执行fixture函数")

fixture函数定义时,需要写上装饰器@pytest.fixture

scope:表示fixture函数的作用域,不指定时,默认是function

session:一次pytest执行中,fixture只会被执行一次,不管有多少条用例,只会被执行一次

package:在一个包中,fixture只会执行一次

module:在一个模块(py文件)中,fixture只会执行一次

class:在一个类中,fixture只会被执行一次

function:在一个函数或者方法中,该fixture只会被执行一次

autouse:表示该fixture函数是否被自动调用,默认是False,Ture会默认调用

autouse为False时,需要主动调用,

调用方式1:需要写装饰器@pytest.mark.usefixtures("fixture函数名称"),可以放在类上面,也可以放在用例上面

调用方式2:把fixture函数传递给测试用例,def test_1(self,A,B,fixture_name):

8、

conftest.py和fixture

conftest.py是pytest测试框架的一个特殊文件,名称是固定的,可以被用来管理自定义fixture,也可以用来重写pytest的一些钩子函数(pytest的内置函数,可以重写里面的内容),这个文件在一个项目中可以有多个,在自己的包下生效,但是建议用一个,在pytest执行时,会自动扫描conftest里的代码,根据各个函数定义的规则执行

fixture后置处理

yield下一行表示后置处理

@pytest.fixture(scope="session",autouse=True)

def buyer_login_fixture():

buyer_login()

yield #yield的下一行表示后置处理

print("用例执行完成,退出登录")

fixture数据返回

有返回值的fixture函数在测试用例中调用函数名称,函数名称在用例的内部使用时就代表他的返回值,返回的数据直接写在yield后面

@pytest.fixture(scope="session",autouse=True)

def get_token():

resp = buyer_login()

token = resp.json()["access_token"]

yield token#yield的下一行表示后置处理

print("用例执行完成,退出登录")

def test_token(self,get_token):

print(get_token)

钩子函数

用例执行后在显示台上中文显示乱码,解决控制台上的乱码问题,可以在conftest中重写pytest的一个钩子函数

@pytest.fixture(scope="session",autouse=True)

def get_token():

resp = buyer_login()

token = resp.json()["access_token"]

yield token#yield的下一行表示后置处理

print("用例执行完成,退出登录")

def test_token(self,get_token):

print(get_token)

Pytest测试框架学习_第3张图片

from typing import List

import pytest

def pytest_collection_modifyitems(items:List["Item"]):

#item对象是pytest收集到的所有的用例对象

for item in items:

#item就代表一条用例

item._nodeid = item._nodeid.encode('utf-8').decode('unicode-escape')

重写完再执行用例

from typing import List

import pytest

def pytest_collection_modifyitems(items:List["Item"]):

#item对象是pytest收集到的所有的用例对象

for item in items:

#item就代表一条用例

item._nodeid = item._nodeid.encode('utf-8').decode('unicode-escape')

Pytest测试框架学习_第4张图片

9、常用插件

失败重试

安装插件  pip install pytest-rerunfailures -i https://pypi.douban.com/simple

命令行执行,全局性的指定,使用用例都遵循这个失败重试的规则,--reruns 3表示最大重试次数

pytest -sv --reruns 3 pytest_study\test_buy_now_api.py

装饰器指定

可以用于指定特定的用例失败重试次数

reruns_delay=10表示每次重试的时间延迟,单位是秒

@pytest.mark.flaky(rerun=2,reruns_delay=10)

多断言插件

安装插件

pip install pytest-assume -i Simple Index

只能写在测试用例里面,不能写在普通函数里面

重复执行

安装插件

pip install pytest-repeat -i Simple Index 

命令行执行

pytest -是v--count 5 pytest_study\test_buy_now_api.py

allure测试报告

安装插件

pip install allure-pytest -i https://pypi.duoban.com.simple

使用:

1、命令参数用来收集参数结果数据,表示allure这个插件在执行pytest测试的过程中会测试结果数据收集到./report/data这个目录,会在当前目录创建report/data的目录,--clean-alluredir表示每次执行都去清除以前的测试结果数据,-sv表示详细日志

pytest -sv --alluredir ./report/data --clean-alluredir

2、使用allure报告生成的工具生成html报告

官网安装文件,配置环境比那辆到path中,命令行验证allure --version

如果提示java_home不对,说明电脑没有装jdk,或者java_home配的不对,就需要安装jdk或者检查java环境

查看报告,report/data值的是测试结果数据目录,就是第一步生成的

allure serve report/data

10、整体执行入口以及pytest.ini文件

在pytest_study文件下创建pytest.ini,内容如下

addopts:指定pytest执行时的命令行参数

testpaths:指顶要执行的参数目录,./表示当前目录

python_file:表示要执行的参数文件,或者测试文件命名规则

python_classes:表示要执行的参数类,或者测试类命名规则

python_functions:表示要执行的测试方法或者测试文件,或者他们的命名规则

[pytest]
addopts = -sv --alluredir ./report/data --clean-alluredir
testpaths = ./
python_files = test_*.py
python_classes = Test*
python_function = test_*

在pytest_study目录下创建run.py,该文件作为整体执行入口出现

import os

import pytest

if __name__ == '__main__':
    #pytest.main()自动扫描当前pytest.ini中相关的配置,根据配置执行测试
    pytest.main()
    #直接打开测试报告,os库可以执行命令行命令
    os.system("allure serve report/data")

你可能感兴趣的:(pytest,学习,python)