Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解

在这里插入图片描述
这些是之前的文章,里面有一些基础的知识点在前面由于前面已经有写过,所以这一篇就不再详细对之前的内容进行描述
Python自动化测试实战篇(1)读取xlsx中账户密码,unittest框架实现通过requests接口post登录网站请求,JSON判断登录是否成功

Python自动化测试实战篇(2)unittest实现批量接口测试,并用HTMLTestRunner输出测试报告

Python自动化测试实战篇(3)优化unittest批量自动化接口测试代码,ddt驱动+yaml实现用例调用,输出HTMLTestRunner测试报告

Python自动化测试实战篇(4)selenium+unttest+ddt实现自动化用例测试,模拟用户登陆点击交互测试,Assert捕获断言多种断言

Python自动化测试实战篇(5)优化selenium+unittest+ddt,搞定100条测试用例只执行前50条

Python自动化测试实战篇(6)用PO分层模式及思想,优化unittest+ddt+yaml+request登录接口自动化测试

Python自动化测试实战篇(7),初识pytest做一个简单的接口测试,allure输出可视化测试报告
Python自动化测试实战篇(8),pytest 测试用例初始化的五种方法与清洗方法
Python自动化测试实战篇(9),一口气学完pytest用例结构、测试框架结构、断言assert
Python自动化测试实战篇(10),一文吃透,Pytest 参数化与标记测试用例,测试用例失败重跑

pytest中fixture的作用

pytest中常用框架就是setup和teardown为代表,pytest区别于这里面的功能,做到了更加简洁,而且在fixture中可以随意命名,没有固定格式之分,所以在pytest中使用selenium或者是appium将会变得更加简单快捷。
fixture只要被当成装饰器引用即可简单使用,不用再去考虑其他的框架结构,下面就是一个简单接口测试案例。

import pytest
import requests
url = "http://127.0.0.1"

payload={}
headers = {
   'User-Agent': 'fox/1.0.0 ',
   'Accept': '*/*',
   'Host': '127.0.0.1:4523',
   'Connection': 'keep-alive'
}
@pytest.fixture()
def login():
    print("接口连接")
class TestFixture:
    def test_case001(self, login):
        response = requests.request("GET", url, headers=headers, data=payload)
        assert response.status_code == 200
        print("接口连接成功")
        print(response.text)

if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第1张图片

SCOPE就是用来控制Fixture的作用范围

其中有5个作用域

function:默认作用域,每个测试用例都运行一次。

class:每个测试类只执行一次。

@pytest.fixture(scope='class')
def login():
    print("接口连接")
class TestFixture:
    def test_case001(self,login):
        response = requests.request("GET", url, headers=headers, data=payload)
        assert response.status_code == 200
        print("接口连接成功")
        print(response.text)

    def test_case002(self,login):
         response = requests.request("POST", url, headers=headers, data=payload)
         print(response.text)

if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

可以看到第一次调用后就开始执行
Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第2张图片

module:每个模块只执行一次

@pytest.fixture(scope='class')
def login():
    print("接口连接")
class TestFixture:
    def test_case001(self,login):
        response = requests.request("GET", url, headers=headers, data=payload)
        assert response.status_code == 200
        print("接口连接成功")
        print(response.text)

    def test_case002(self,login):
         response = requests.request("POST", url, headers=headers, data=payload)
         print(response.text)

if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

可以看到module会从每一个模块都执行一遍

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第3张图片

package:每个python包只执行一次

@pytest.fixture(scope='package')
def login():
    print("package:每个python包只执行一次")
class TestFixture:
    def test_case001(self,login):
        response = requests.request("GET", url, headers=headers, data=payload)
        assert response.status_code == 200
        print("接口连接成功")
        print(response.text)

    def test_case002(self,login):
         response = requests.request("POST", url, headers=headers, data=payload)
         print(response.text)
    def test_case003(self,login):
         print("用例3")

if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第4张图片

session:整个会话只执行一次,即运行项目时整个过程只执行一次

@pytest.fixture(scope='session')
def login():
    print("session:整个会话只执行一次,即运行项目时整个过程只执行一次")
class TestFixture:
    def test_case001(self,login):
        response = requests.request("GET", url, headers=headers, data=payload)
        assert response.status_code == 200
        print("接口连接成功")
        print(response.text)

    def test_case002(self,login):
         response = requests.request("POST", url, headers=headers, data=payload)
         print(response.text)
    def test_case003(self,login):
         print("用例3")

if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第5张图片

fixture作为参数如何使用?

fixture中5个参数分别是scope,params,autouse,ids和name。
scope:控制Fixture的作用范围
autouse:控制Fixture自动测试
ids:自定义fixture内参数内容
name:默认fixture函数名称
name参数也可以对fixture进行命名
params:指定Fixture的参数化内信息

yield的用法

yield代替return进行参数传递

用于起到代码进行分割,类似与setup和teardown作用,yield都可以进行返回值,用于返回作用

import pytest
@pytest.fixture(autouse=True)
def tx1():
    print("开始")
    yield 100
def test_e(tx1):
    print("执行tx1")
    print(tx1)
    assert tx1 == 100
if __name__ == '__main__':
    pytest.main(["-s","test3.py"])

    
    

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第6张图片

yield进行数据间的传递

import pytest
import requests
url = "http://127.0.0.1:4523/m1/2459729-0-default/registersearch?user=admin&password=123456"

payload={}
headers = {
   'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
   'Accept': '*/*',
   'Host': '127.0.0.1:4523',
   'Connection': 'keep-alive'
}

@pytest.fixture(autouse=True)
def login():
    response = requests.request("GET", url, headers=headers, data=payload)
    yield response
    print("清空数据")
class TestFixture:
    def test_case001(self,login):
        res = requests.request("GET", url, headers=headers, data=login)
        assert res.status_code == 200
        print("接口连接成功")
        print(res.text)


if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第7张图片

yield的执行顺序

import pytest
import requests
@pytest.fixture()
def test_1():
    print("Testing1")
    yield 1
    print("Testing2")
@pytest.fixture()
def test_2(test_1):
    print("执行test1")
    yield 2
    print("清除数据")
@pytest.fixture()
def fixture_add(test_1, test_2):
    print("执行test1+test2")
    result = test_1+test_2
    yield result
    print("Test")
def test_demo(fixture_add):
    print("总和")
    assert fixture_add ==3
if __name__ == '__main__':
    pytest.main(["-s","test3.py"])


Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第8张图片
先执行test1,再执行test1+test2,最后全部总和

终结函数:finalizer

pytest中除了可以用yield和teardown作为执行用例的终结外还可用finalizer作为终结函数
Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第9张图片
直接对已经生成的数据进行终结

import pytest
import requests
url = "http://127.0.0.1:4523/m1/2459729-0-default/registersearch?user=admin&password=123456"

payload={}
headers = {
   'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
   'Accept': '*/*',
   'Host': '127.0.0.1:4523',
   'Connection': 'keep-alive'
}

@pytest.fixture(autouse=True)
def login():
    response = requests.request("GET", url, headers=headers, data=payload)
class TestFixture:
    def test_case001(self,login):
        res = requests.request("GET", url, headers=headers, data=login)
        requests.addfinalizer(login)
        assert res.status_code == 200
        print("接口连接成功")
        print(res.text)


if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

执行终结之后就会发现数据已经被删掉,这一条测试用例执行错误。
Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第10张图片

多重终结

可以对多个函数进行分批终结

import pytest
import requests

@pytest.fixture
def tx_first(request):
    print("第一次执行")

    # 定义终结函数
    def tx1():
        print("\n清除数据第一个")

    def tx2():
        print("\n清除数据第二个")

    # 注册为终结函数
    request.addfinalizer(tx1)
    request.addfinalizer(tx2)

def test_2(tx_first):
    print("\n执行tx1")

def test_1(tx_first):
    print("\n执行tx2")

if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第11张图片
可以看到先从第二个开始执行然后再执行对一个,再多重终结中函数的执行顺序是倒序。

conftest.py的使用

conftest.py用来单独存放fixture的文件,需要与用例的运行文件放在一起,如果希望共享这个文件则可以放在根目录下

conftest.py不需要import可以自动被pytest找到,可以将fixture都放在conftest中,把它当成fixture的仓库使用。

conftest也可以在测试函数执行前后执行连接数据库,打开文件,爬虫等操作。

创建一个conftest.py文件存在单独目录中与其他测试用例一起存放
Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第12张图片

conftest.py

import pytest
import requests
@pytest.fixture()
def into():
        print("开始执行操作")
        yield
        print("结束")

test.py

import pytest
def test1(into):
    print("执行conftest内的内的fixture内容")

if __name__ == '__main__':
    pytest.main(["-vs", "test.py"])

运行后可以看到用例执行conftest.py中的fixture

Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第13张图片

autose参数使用方法

autose默认为False,当它为True时可以自动调用里面的功能不用次次都去调用

import pytest
import requests
url = "http://127.0.0.1:4523/m1/2459729-0-default/registersearch?user=admin&password=123456"

payload={}
headers = {
   'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
   'Accept': '*/*',
   'Host': '127.0.0.1:4523',
   'Connection': 'keep-alive'
}

@pytest.fixture(autouse=True)
def login(request):
    response = requests.request("GET", url, headers=headers, data=payload)
    print(response.text)
    yield
    print("测试结束")
class TestFixture:
    def test_case001(self,login):
        res = requests.request("GET", url, headers=headers, data=login)
        assert res.status_code == 200
        print("接口连接成功")
        print(res.text)
def test_case002(request):
    print(request)
    print("测试用例2")


if __name__ == '__main__':
    pytest.main(["-vs", "test3.py"])

如下所示test_case002直接调用login中的功能,每个用例都可以自动调用,自动进行使用,而不用重复去写功能。当然autose也可以和其他的fixture混合使用
Python自动化测试实战篇(11),pytest测试用例生命周期管理,fixture用法详解_第14张图片

在这里插入图片描述

你可能感兴趣的:(软件测试,python,pytest,测试用例,fixture用法详解,生命周期管理)