Python单元测试框架总结

发表于:2021-2-23 09:13

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:郎显磊 曹睿    来源:51Testing软件测试网原创

  1、Unittest
  unittest是Python标准库中自带的单元测试框架。有时候也被称为PyUnit。就像JUnit是Java语言的标准单元测试框架一样,unittest(PyUnit)则是Python语言的标准单元测试框架,官方维护。支持自动化测试测试用例的初始化和关闭,测试用例的聚合等功能。
  unittest中最核心的四个概念是:testcase(测试用例), testsuite(测试用例集),testrunner(测试执行),testfixture(测试装置)。
  Testcase测试用例,每个测试方法以 test 开头,自动被unittest识别的。
  TestSuite测试用例集,通过类(class)的方式,将测试用例组织在一起。
  Testloader用来加载TestCase到TestSuite中,loadTestsFrom__()方法,寻找TestCase,创建它们的实例,然后add到TestSuite中,再进行返回。
  TextTestRunner执行测试用例,run(test)会执行TestSuite/TestCase中的run(result)方法,测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
  fixture测试用例环境的搭建和销毁。setUp()和tearDown()两个方法,在每个测试方法执行前以及执行后执行一次,setUp用来为测试准备环境,tearDown用来清理环境,以备之后的测试。
  Unittest使用流程:定义一个TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,我们通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者我们可以直接通过TextTestRunner来执行用例。
  参数:verbosity参数可以控制执行结果的输出,0是简单报告、1是一般报告、2是详细报告。可以通过addTest和addTests向suite中添加case或suite,也可以用TestLoader的loadTestsFrom__()方法。使用setUp()、tearDown()、setUpClass()以及tearDownClass()可以在用例执行前布置环境,以及在用例执行后清理环境。可以通过skip,skipIf,skipUnless装饰器跳过某个case,或者用TestCase.skipTest方法。参数中加stream,可以将报告输出到文件:可以用TextTestRunner输出txt报告,以及可以用HTMLTestRunner输出html报告。可以结合代码覆盖率工具coverage,进行代码覆盖率统计。
  可以统计行和分支覆盖率(coverage run --branch test.py)。
  2、Autotest
  Autotest是Google、Redhat、IBM公司联合开发的分布式自动化测试框架,兼顾软硬件测试。基于Python,用于操作系统内核冒烟测试、服务器硬件验证等。使用Autotest有两个前提:被测机上需安装Python;测试发起机器与被测机间要建立无密码SSH信任关系。
  3、Testoob
  testoob是一个针对python的高级单元测试框架。它集成了现有的PyUnit(模块“UNITTEST”)测试套件,便于使用和进行扩展。目前使用人数和社区生态均较少。
  4、Doctest
  doctest是一个Python发行版自带的标准模块,利用文档的形式模拟代码的执行操作。采用交互式会话的Python代码片段,测试执行并验证结果,代码和测试用例没有进行分离。
  5、The Haskell Test Framework
  允许一种简单方便的方式进行黑匣子测试,自动收集测试定义的自定义预处理器。预处理器允许用准确的文件名和行号信息报告失败的测试用例。可以为失败的测试生成高度可读的输出,目前用于单元测试使用人数较少。
  6、Twisted Trial
  对PyUnit的扩展,trial是Twisted的测试脚本程序,针对Linux的,编译好的trial在Windows下无法直接运行,目前用于单元测试使用人数较少。
  7、ShouldDSL
  分布式测试工具,应用较少。
  8、Green
  Python测试运行程序,应用于单元测试人数较少。
  9、Mock
  Python用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为,然后验证后续的执行是否正确。在进行单元测试的时候,可以指定任何对象的返回值,便于测试对外部接口有依赖的代码(导入型代码)。从Python 3.3开始,mock模块已经被合并到标准库中,被命名为unittest.mock,可以直接进行使用。
  10、MOX
  Python的基于mock的单元测试框架。应用案例和使用人数相对较少。
  11、Tox
  通用的虚拟环境管理和测试命令行工具。tox能够让我们在同一个Host上自定义出多套相互独立且隔离的python环境。用于运行静态代码分析、测试工具和自动化程序包构建,但应用单元测试较少。
  12、Pytest
  pytest是根据MIT许可的条款发行的免费和开源软件。
  pytest是Python另一个第三方单元测试库。它的目的是让单元测试变得更容易,并且也能扩展到支持应用层面复杂的功能测试。pytest兼容unittest框架的代码,可以用来运行unittest测试用例。
  pytest的特性有:
  1)支持用简单的assert语句实现丰富的断言,无需复杂的self.assert*函数。
  2)自动识别测试模块和测试函数。
  3)兼容unittest和nose测试集。
  4)支持Python3和PyPy3。
  5)丰富的插件生态,已有300多个各式各样的插件,和活跃的社区。
  用例编写:pytest支持函数、测试类形式的测试用例。并且可以方便地使用 assert语句进行断言,不用担心在 nose 或 unittest 中产生的缺失详细上下文信息的问题。
  用例发现和执行:unittest 和 nose 所支持的用例发现和执行能力,pytest 均支持。pytest 支持用例自动(递归)发现:
  默认发现当前目录下所有符合 test_*.py 或 *_test.py 的测试用例文件中,以 test 开头的测试函数或以 Test 开头的测试类中的以 test 开头的测试方法。执行指定用例:指定测试文件路径(pytest /path/to/test/file.py)、
  指定测试类(pytest /path/to/test/file.py:TestCase)、指定测试方法(pytest another.test::TestClass::test_method)、指定测试函数(pytest /path/to/test/file.py:test_function)。
  测试装置(Fixtures):它不但能实现setUp和tearDown这种测试前置和清理逻辑,还其他非常多强大的功能。
  1)pytest支持依赖注入机制,你无需通过from xx import xx的形式显示导入,只需要在测试函数的参数中指定同名参数即可。
  2)共享:在 pytest 中,同一个测试夹具可被多个测试文件中的多个测试用例共享。只需在包(Package)中定义 conftest.py 文件,并把测试夹具的定义写在该文件中,则该包内所有模块(Module)的所有测试用例均可使用 conftest.py 中所定义的测试夹具。
  3)nittest 和 nose 均支持测试前置和清理的生效级别:测试方法、测试类和测试模块。pytest 的测试夹具同样支持各类生效级别,且更加丰富。通过在 pytest.fixture中指定scope参数来设置:function——函数级,即调用每个测试函数前,均会重新生成 fixture;class——类级,调用每个测试类前,均会重新生成 fixture;module——模块级,载入每个测试模块前,均会重新生成 fixture;package——包级,载入每个包前,均会重新生成 fixture;session ——会话级,运行所有用例前,只生成一次 fixture,通常用于全局系统初始化。
  4)测试前置和清理:pytest 的测试夹具也能够实现测试前置和清理,通过 yield 语句来拆分这两个逻辑。yield smtp_connection 及前面的语句相当于测试前置,通过 yield 返回准备好的测试资源 smtp_connection; 而后面的语句则会在用例执行结束(确切的说是测试夹具的生效级别的声明周期结束时)后执行,相当于测试清理。
  5)跳过测试和预计失败:pytest 除了支持unittest和nosetest的跳过测试和预计失败的方式外,还在 pytest.mark 中提供对应方法:通过skip装饰器或 pytest.skip函数直接跳过测试;通过skipif按条件跳过测试;通过 xfail预计测试失败。
  6)子测试参数化测试:pytest除了支持unittest中的 TestCase.subTest,还支持一种更为灵活的子测试编写方式,也就是参数化测试,通过 pytest.mark.parametrize 装饰器实现。在下面的示例中,定义一个test_eval 测试函数,通过 pytest.mark.parametrize 装饰器指定 3 组参数,则将生成 3 个子测试。
  用例执行结果:不需要main函数,pytest自动识别test_开头的测试方法(用例)。使用 pytest 去执行用例时,它会输出详细的(且是多种颜色)上下文信息,既输出了测试代码上下文,也输出了被测变量值的信息。通过或不通过会用不同的颜色进行区分,测试结果输出布局更加友好易读。相比于 nose 和 unittest,pytest 允许用户使用更简单的方式编写测试用例。
  13、Nose/nose2
  nose是Python的一个第三方单元测试框架,完全兼容 unittest。python自带框架unttest的扩展,使测试更简单高效,也是一个开源的项目。
  nose已经进入维护模式,继承nose的是nose2,但要注意的是,nose2并不支持nose的全部功能,nose2的主要目的是扩展Python的标准单元测试库unittest,因此它的定位是“带插件的unittest”。nose2提供的插件,例如测试用例加载器,覆盖度报告生成器,并行测试等内置插件和第三方插件,让单元测试变得更加完善。
  nose 相较于 unittest 一个最大的优势就是插件体系,自带了很多有用的插件,也有丰富的第三方插件,当 nose 本身不能够完全满足我们的测试需求时,可以通过安装插件,并在 nosetests 命令行指定该插件所提供的特定参数即可非常容易的使用插件。
表1 单元测试工具对比(来源:GitHub)

      版权声明:本文出自51Testing会员投稿,51Testing软件测试网及相关内容提供者拥有内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号