Test in Python

Page content

Test in Python

写在前面

Getting Started With Testing in Python – Real Python

本文部分翻译自上文。

如何用 pytest 进行高效测试 - 明月轩 | LibertyDream


Test your code

有很多方法可以测试代码。在本教程中,您将学习最基本的步骤中的技术,并学习高级方法。

自动测试vs手动测试?

日常通过print或者运行一小段程序进行的测试叫探索性测试,其实就是手动测试的一种。要实现完整的对代码的测试,需要进行诸如不同的输入类型亦或是预期结果的测试。每次对代码进行更改的时候,都需要对上述的项目进行测试检查。这就引出了自动测试,即通过脚本对代码进行自动化测试。

单元测试vs集成测试

集成测试,也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。一些局部反映不出来的问题,在全局上很可能暴露出来。

集成测试也存在一个问题是,如果不能很好的隔离每部分的话,很难排查是哪部分出的问题。

单元测试是单独测试一个小组件,验证其功能是否正确。

综上:

集成测试检查应用程序中的组件是否相互运行。

单元测试检查应用程序中的一个小组件。


选择一个测试工具

有三种主要的测试框架

  • unittest

python内置的测试框架,所以在很多py项目或者商业应用中可以看到它的身影。unittest既是一个testing framework也是test runner。

unittest:

  • 把测试写作类的方法
  • unittest.TestCase类中写一系列的特殊的断言方法,而不是内置的assert

使用方法

  1. 导入unittest
  2. 创建测试类,继承TestCase
  3. 测试函数写成类的方法
  4. unittest.main()执行测试

    import unittest
      
    class TestSum(unittest.TestCase):
    	def test_sum(self):
    		self.assertEqual(sum([1,2,3]), 6, "Should be 6")
              
    if __name__=="__main__":
      unittest.main()
    

unittest — Unit testing framework — Python 3.10.3 documentation

  • nose / nose2

随着时间的推移,当您为应用程序编写数百甚至数千个测试时,理解和使用unittest的输出变得越来越困难。

nose与使用unittest框架编写的任何测试都兼容,可以作为unittest runner的替代品。nose作为开源应用程序的开发落后了,于是创建了一个名为nose2的分支。如果你是从零开始,建议你使用nose2而不是nose。

要开始使用nose2,请从PyPI安装nose2,并在命令行上执行它。NOS2将尝试发现所有名为test*的测试脚本。从unittest继承的py和测试用例。当前目录中的TestCase:

  $ pip install nose2
  $ python -m nose2
  .F
  ======================================================================
  FAIL: test_sum_tuple (__main__.TestSum)
  ----------------------------------------------------------------------
  Traceback (most recent call last):
    File "test_sum_unittest.py", line 9, in test_sum_tuple
      self.assertEqual(sum((1, 2, 2)), 6, "Should be 6")
  AssertionError: Should be 6
  
  ----------------------------------------------------------------------
  Ran 2 tests in 0.001s
  
  FAILED (failures=1)

您刚刚执行了在test_sum_unittest中创建的测试。来自nose2 test runner。NOS2提供了许多命令行标志,用于过滤您执行的测试。有关更多信息,您可以浏览Nose 2文档。

  • pytest

pytest支持执行unittest测试用例。pytest的真正优势在于编写pytest测试用例。pytest测试用例是Python文件中的一系列函数,以test_3;开头。

pytest还有其他一些很棒的功能:

  1. 支持内置的assert语句,而不是使用特殊的断言
  2. 支持过滤测试用例
  3. 能够从上次失败的测试中重新运行
  4. 一个由数百个插件组成的生态系统来扩展功能

    def test_sum():
      assert sum([1, 2, 3]) == 6, "Should be 6"
      
    def test_sum_tuple():
      assert sum((1, 2, 2)) == 6, "Should be 6"
    

使用pytest编写测试

pytest绝对性优于unittest,想看unittest的看原文

安装

pip install -U pytest

项目示例

Folder
	|- programs
		|- code1.py
		|- code2.py
	|- tests
		|- test_code1.py
		|- test_code2.py

pytest会自动匹配当前目录的test_*.py文件和*_test.py文件

用类将测试用例归组:

class TestClass:
	def test_one(self):
		assert "h" in "this"
	def test_two(self):
		assert hasattr('hello', 'check')

归类的好处:

  • 组织测试代码
  • 共享测试夹具
  • 类级别用mark,让他们隐式的用于所有的测试代码

    # content of test_class_demo.py
    class TestClassDemoInstance:
    value = 0
    
    def test_one(self):
        self.value = 1
        assert self.value == 1
    
    def test_two(self):
        assert self.value == 1
    

未完待续