当前位置:网站首页>gtest从一无所知到熟练使用(2)什么是测试夹具/装置(test fixture)
gtest从一无所知到熟练使用(2)什么是测试夹具/装置(test fixture)
2022-07-04 20:48:00 【奇妙之二进制】
在介绍gtest之前补充介绍几个测试术语。
Fixture是软件测试中的一个重要概念。许多人对这个概念感到模糊,原因之一是迄今为止它没有统一的中文翻译。有人叫它测试固件,有人叫它测试装置,还有人叫它测试夹具。我个人没有特别倾向的翻译,因此在文中直接称之为Fixture。
那么,到底什么是Fixture呢?实际上,Fixture概念源于电子学,指的是测试电子元器件所需的辅助装置。后来这个概念被引入到软件测试领域,意指能够提供软件测试所依赖的系统,环境,状态等前置条件的东西。
在我看来,Fixture是一个抽象事物,其抽象性体现在两方面。
一方面,Fixture的功能是抽象的。测试用例的前置条件千变万化,Fixture的具体功能也随之千变万化。例如,一个读取文件内容的测试用例,其前置条件是一个打开的文件,此时Fixture的功能是打开文件;而一个测试HTTP接口的测试用例,其前置条件是一对运行的HTTP服务器/客户端,此时Fixture的功能是创建并启动HTTP服务器/客户端。
另一方面,Fixture的形态也是抽象的。即使是同一个测试用例,在不同测试环境下,Fixture可能存在不同的形态。例如,针对读取文件内容的测试用例,Fixture的作用是打开文件,但是其具体的实现方式有多种可能。既可以是一个双击文件图标的操作,也可以是一行Linux命令,还可以是一段Python脚本。
由于Fixture在功能和形态两方面都是抽象的,因此也不难理解为什么许多人对Fixture有一种似懂非懂的感觉。这里,根据上面的讨论,我们给Fixture下一个自己的定义: Fixture是在软件测试过程中,为测试用例创建其所依赖的前置条件的操作或脚本。
需要补充的是,“凡事有始就有终”,Fixture也一样。在执行测试用例前需要准备环境,那么在用例执行之后还需要恢复环境。因此,Fixture还有一个隐含的功能,那就是在测试结束后,恢复测试环境,回归初始状态。
聊到这里,大家可能还是对Fixture的意义不理解。准备和销毁环境,初始化和清除状态,为什么不直接由测试用例自己来完成?"无中生有"弄出一个Fixture,会不会把简单问题复杂化?
这是好问题。这些操作当然能由测试用例自己来完成。然而,“能不能"不是关键,关键是"好不好”。
软件测试有个特点,那就是针对同一用户场景,往往会设计多个前置条件相同但是测试步骤有差异的测试用例(测试套件Test Suite的概念即源于此)。此时,如果每个用例都各自维护前置条件,不仅存在浪费,而且难以保持一致性。
一种更好的做法是"合并同类项"。当多个用例具有相同的前置条件时,我们可以将前置条件提取出来,作为Fixture,由各个用例共同调用。这种做法效率高,易于维护,一致性也更好。
从设计模式角度来看,这种做法遵守了两大原则。一是"单一数据源"(Single Source of Truth)原则,即完成某一功能的Fixture有且仅有一份;二是"关注点分离"(Separation of Concerns)原则,即让Fixture负责测试环境和状态的准备与销毁工作,让测试用例负责测试主体工作,双方各司其职,职责明细。
至此,我们从理论方面介绍了Fixture的原理和含义。接下来,我们从实践方面看看,Fixture是如何应用于工程实际的。
一种最普遍的实现Fixture的方式是Setup/Teardown。它广泛存在于各种主流的自动化测试框架中,例如C++ Google Test, Java JUnit, Python Unittest, Robot Framework等。
它们共同的特点是基于Setup函数或方法,完成对测试环境和状态的准备工作;基于Teardown函数或方法,完成对测试环境和状态的销毁工作。
在基于Setup/Teardown的测试框架中,测试用例的一般过程包括四部分: Setup -> 执行用例,与被测软件进行交互 -> 验证结果,与期望值进行比较 -> Teardown,回到初始状态。
我们可以定义不同级别的Setup/Teardown方法,来实现不同范围的Fixture共享。例如,在用例中定义的Setup,只在这个用例执行之前调用;在Suite中定义的Setup,只在Suite执行之前调用,在Suite中的所有测试用例执行时不再调用。
基于Setup/Teardown的Fixture实现方式存在时间长,应用范围广,“江湖地位高”。不过,近年来,出现另外一种Fixture实现方式,渐渐被人认识。它就是Pytest Fixture。
Pytest是Python单元测试框架"三剑客"之一。与Python Unitest, Python Nose不同的是,Pytest不仅支持单元测试,还支持各种复杂的功能测试,UI测试和端到端测试。Pytest"宽应用光谱"的原因之一,是它采用了新的Fixture实现方式。
在Pytest中,基于@pytest.fixture装饰器,任意Python函数都可以被注册为Fixture。Fixture的名字即是Python函数的名字。测试用例(即测试函数)通过将Fixture名字声明在输入参数表中的方式,来选择和使用Fixture。
将Fixture定义为函数,可以实现Fixture的模块化。Fixture既可以调用各种库和模块,也可以被其他Fixture以输入参数声明的方式嵌套调用。与Setup/Teardown不同的是,Pytest Fixture不仅可以在Case和Suite范围共享,还可以在Package和Session范围共享。
以输入参数声明方式调用Fixture的另一个好处是可以实现细粒度的Fixture选择和组合。每个测试用例都可以将各自所依赖的Fixture放在输入参数表中,而将不依赖的Fixture剔除。重复出现的Fixture组合可以被封装成一个新的Fixture。Setup/Teardown方式就没有这种灵活度。
另外,Pytest Fixture支持参数化。针对同一个测试用例,根据不同的参数配置,可以在执行用例的过程中动态地调用不同的Fixture。这样,可以实现一个测试用例覆盖多种场景的需求。基于参数化的Fixture,数据驱动测试更容易实现,也更好维护。
大家可以看到,与传统的Setup/Teardown模式相比,Pytest Fixture模式使用更加方便,功能也更强大。个人认为,Pytest Fixture模式未来的前景值得期待。
总结一下,本文介绍了:
Test Fixture的产生背景和意义,
Test Fixture的概念和特点,
两种Test Fixture实现模式: Setup/Teardown和Pytest Fixture各自的含义和特点。
希望通过阅读本文,大家对"Test Fixture"不再陌生或迷糊,这方面的认识和理解能够上一个台阶。
边栏推荐
猜你喜欢
【LeetCode】17、电话号码的字母组合
Operation of adding material schedule in SolidWorks drawing
【公开课预告】:视频质量评价基础与实践
解析steam教育中蕴含的众创空间
华为ensp模拟器 DNS服务器的配置
一文掌握数仓中auto analyze的使用
[C language] deep understanding of symbols
Configuration of DNS server of Huawei ENSP simulator
[wechat applet] collaborative work and release
Flutter TextField示例
随机推荐
WGCNA analysis basic tutorial summary
Le module minidom écrit et analyse XML
为什么说不变模式可以提高性能
How much is the minimum stock account opening commission? Is it safe to open an account online
迈动互联中标北京人寿保险
[ 每周译Go ] 《How to Code in Go》系列文章上线了!!
2021 CCPC 哈尔滨 I. Power and Zero(二进制 + 思维)
杰理之AD 系列 MIDI 功能说明【篇】
MYSQL 用!=查询不出等于null的数据,解决办法
华为模拟器ensp常用命令
Jerry added the process of turning off the touch module before turning it off [chapter]
MP3是如何诞生的?
一文掌握数仓中auto analyze的使用
输入的查询SQL语句,是如何执行的?
更强的 JsonPath 兼容性及性能测试之2022版(Snack3,Fastjson2,jayway.jsonpath)
Golang面试整理 三 简历如何书写
redis缓存
Huawei ENSP simulator realizes communication security (switch)
The video sound of station B is very low - solution
学习突围3 - 关于精力