• 12
  • 12
分享
  • pytest测试夹具fixture简介——软件测试圈
  • 恬恬圈 2021-12-22 10:42:20 字数 4813 阅读 5293 收藏 12

一、Fixture介绍

Fixture是Pytest精髓所在,就像Unittest中的setup和teardown一样,但相对之下它的功能更加强大和灵活。

二、Fixture的作用

做测试前后的初始化设置,如测试数据准备,链接数据库,打开浏览器等这些操作都可以使用Fixture来实现;

测试用例的前置条件可以使用Fixture实现;

支持经典的xunit Fixture ,像Unittest使用的setup和teardown;

Fixture可以实现Unittest不能实现的功能,比如unittest中的测试用例和测试用例之间是无法传递参数和数据的,但是Fixture却可以解决这个问题。

三、Fixture定义及调用

Fixture通过@pytest.fixture()装饰器装饰一个函数,那么这个函数就是一个Fixture,看个实例: 

import pytest
from selenium import webdriver
@pytest.fixture()
def manage_browser():
    # 前置条件
    driver = webdriver.Chrome()
    return driver
    # 后置条件
    print("后置条件")
@pytest.mark.fixe
def test_baidu(manage_browser):
    driver = manage_browser
    driver.get("https://www.baidu.com/")

声明的测试夹具函数名称,作为参数传入其他函数,即可完成调用。可以传多个Fixture,按先后顺序执行。

1.png

上面的测试夹具中只用return返回初始化浏览器,return后面的后置条件不会执行,因此需要将return改成yield,后置条件就会被调用执行。

Yield是Python中的一个关键字,表示生成器。测试夹具的前置条件遇到yield时返回一个结果,然后将测试夹具挂起,转而去执行测试用例,最后回来测试夹具中执行后置条件。Return和yield后面可以不写任何返回值,表示空没有数据返回。Yield使用示例如下:

import pytest
from selenium import webdriver
@pytest.fixture()
def manage_browser():
    # 前置条件
    driver = webdriver.Chrome()
    yield driver  # yield,返回函数值,可以继续执行下面的代码
    # 后置条件
    driver.quit()
@pytest.mark.fix
def test_baidu(manage_browser):
    driver = manage_browser  # 这里是参数接收,不能打括号
    driver.get("https://www.baidu.com/")

四、Pytest中fixture前置后置条件

Pytest框架中将前置条件,后置条件单独放在Fixture的函数中,所有的用例调用测试夹具的前后置条件。Web自动化的前后置条件如下:

import pytest
from selenium import webdriver
@pytest.fixture()
def manage_browser():
    """初始化浏览器"""
    driver = webdriver.Chrome()
    # 设置隐式等待
    driver.implicitly_wait(20)
    # 最大化浏览器
    driver.maximize_window()
    # 初始化要用到的页面
    login_page = LoginPage(driver)
    # 初始化首页
    index_page = IndexPage(driver)
    yield driver, login_page, index_page
    # 后置条件
    driver.quit()
@pytest.fixture()  # 可以同时创建多个测试夹具
def login(manage_browser):
    """登录的夹具"""
    driver = manage_browser
    pass

要使用测试夹具,在测试用例类中的test方法中传入夹具函数名(例如上面函数的manage_browser),且框架中所有的测试用例文件中不需要导入夹具函数名,是直接使用的。如下代码:

class TestLogin:
    @pytest.mark.parametrize("test_info", test_data_error)
    def test_01_login_error(self, test_info, manage_browser):
        """登录时,手机号为空"""
        # 拆开元祖中的参数
        driver, login_page, index_page = manage_browser
        # 第一步:登录
        login_page.login(test_info["mobile"], test_info["pwd"])
        # 获取实际结果(封装以后执行的函数或者方法)
        actual = login_page.get_error_msg()
        # 第二步:获取预期结果 test_info["expected"]
        expected = test_info["expected"]
        # 第三步:断言
        # self.assertEqual(expected, actual)  unitte中的断言方式
        assert expected == actual

测试用例类中使用测试夹具,以及数据传递的方式:

2.png

注意:Pytest中的Fixture测试夹具单独放在conftest.py文件中,且conftest.py文件需要与Pytest启动文件放在同一级目录。

3.png

五、Fixture作用域

Unittest框架中setup的作用是每条测试用例执行之前都会执行一次,setupclass的作用是每个测试用例类执行之前都会执行一次。

Pytest的Fixture同样有这样的作用域,且使用更广泛更灵活。

关键代码:@pytest.fixture(scope='作用范围'),参数如下:

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

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

  • module:每个模块只执行一次(模块:一个.py文件);

  • package:每个python包只执行一次;

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

Fixture后面的括号不加任何参数,就代表默认作用域,与function作用一样。

示例一:class --每个测试类只执行一次

import pytest
from selenium import webdriver
test_data = [1, 2, 3]
@pytest.fixture(scope="class")
def manage_browser():
    """初始化浏览器"""
    driver = webdriver.Chrome()
    yield driver
    # 后置条件
    driver.quit()
class TestHelloWord:
    @pytest.mark.parametrize("test_info", test_data)
    def test_helloword(self, test_info, manage_browser):
        pass
    def test_hello(self, manage_browser):
        pass

上面的示例TestHelloWord虽然有4条测试用,但是@pytest.fixture(scope="class")申明了每个测试类只执行一次,所以整个过程只打开了一次浏览器。如果一个.py文件中有2个类,就会打开2次浏览器。

示例一:module  --每个模块只执行一次

import pytest
from selenium import webdriver
test_data = [1, 2, 3]
@pytest.fixture(scope="module")
def manage_browser():
    """初始化浏览器"""
    driver = webdriver.Chrome()
    yield driver
    # 后置条件
    driver.quit()
class TestHelloWork:
    @pytest.mark.parametrize("test_info", test_data)
    def test_helloword(self, test_info, manage_browser):
        pass
    def test_hello(self, manage_browser):
        pass
class TestModule:
    @pytest.mark.parametrize("test_info_2", test_data)
    def test_module(self, test_info_2, manage_browser):
        pass
    def test_module2(self, manage_browser):
        pass

上面的示例中有两个类,8条测试用例,但是测试夹具作用域设为module ----每个模块只执行一次,所以整个过程只打开一次浏览器。

特殊方式:Fixture里面有个参数autouse(自动使用的意思),默认是False,当设置为True时,用例就会自动调用该Fixture功能,这样的话写用例时就不用每次都去传参了。

4.png

六、多个测试夹具

当有多个测试夹具,可以设置不同的作用域,测试用例方法后面可以传需要的测试夹具,也可以传入全部测试夹具。

import pytest
from selenium import webdriver
test_data = [1, 2, 3]
@pytest.fixture(scope="function")
def manage_browser():
    """初始化浏览器"""
    driver = webdriver.Chrome()
    yield driver
    print("后置执行")
    # 后置条件
    driver.quit()
@pytest.fixture(scope="class")
def delete_cookie():
    print("delete cookie before")
    yield
    print("delete cookie after")
class TestHelloWork:
    @pytest.mark.parametrize("test_info", test_data)
    def test_helloword(self, test_info, manage_browser, delete_cookie):
        pass


作者:飞翔的猪~

原文链接:https://www.cnblogs.com/zdx20/p/14948134.html

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 一、 jmeter报告导出执行命令: jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]如下图所示:启动Jmeter,窗口有一行命令,执行后可导出测试结果报告-n: 非GUI模式执行JMeter-t: 执行测试文件所在的位置-l: 指定生成测试结果的保存文件,jtl文件格式-e: 测试结束后,生成测试报告-o: 指定测试报告的存放位置[jmx fi...
            1 1 856
            分享
          •   据泄密者 Majin Bu 称,苹果将于明天推出第11代基础款iPad。Majin Bu 声称,新款 iPad 将采用与第 10 代机型相同的设计,而且配件"将完全兼容"。上周,同一位泄密者声称苹果将首次推出带有可互换磁性笔尖的第三代 Apple Pencil,而今天的传言是在有关苹果明天可能推出的产品的相互矛盾的报道之后出现的。  彭博社的马克-格尔曼(Mark Gurman)周日表示,虽然新款 iPad正在开发中,但预计本月不会推出新机型,而 9to5Mac 和 Supercharged News 的报道则称,苹果计划最快于周二推出新款 iPad mini、iPad...
            0 0 1435
            分享
          • 1、按严重程度分类:是指bug对软件质量的破坏程度,即此bug的存在将对软件的功能和性能产生什么样的影响。崩溃(Blocker):系统无法正常运行。阻碍开发或测试工作的问题;造成系统崩溃、死机、死循环、导致数据库数据丢失,与数据库连接错误,主要功能丧失,基本模块缺失等问题。如:代码错误、死循环、数据库发生死锁、重要的一级菜单功能不能使用等(该问题在测试中较少出现,一旦出现应立即中止当前版本测试)。严重(Critical):很明显的错误性的bug。系统主要功能部分丧失、数据库保存调用错误、用户数据丢失,一级功能菜单不能使用但是不影响其他功能的测试。功能设计与需求严重不符模块无法启动或调用,程序重...
            14 13 3642
            分享
          •   IEEE Spectrum 出炉了 2022 年度最受欢迎编程语言排名。该排名最初由数据记者 Nick Diakopoulos 于 2013 年创建,今年是第九届。当前版本由 IEEE Spectrum 高级编辑 Stephen Cass 维护,并得到 Prachi Patel 和 Michael Novakovic 的开发支持。  作为业内比较权威的交互语言排行榜,本次排名结合了包括谷歌搜索、推特、Stack Overflow、Reddit、IEEE、GitHub 等 8 个来源的 9 项指标,共上榜了 57 种语言。关于指标,例如在 Stack Overflow 中,程序员可以在其中询...
            0 0 904
            分享
          •      昨天的文章中给大家介绍到了批量生成企业数据,今天为大家贴上批量生成个人信息的代码。生成的个人信息数据如下截图:     批量生成个人信息的代码如下:from faker import Faker import xlwt faker = Faker('zh_CN') def add_user_info(number):     work_book = xlwt.Workbook(...
            4 2 3780
            分享
      • 51testing软件测试圈微信