Python单元测试:快速入门

本文的翻译是专门为Python QA工程师课程的学生准备的。


单元代码测试是软件开发生命周期不可或缺的一部分。 单元测试还构成进行回归测试的基础,也就是说,它们可以确保在添加新功能或更改现有功能时,系统将根据场景运行。

在本文中,我将在一堂课中演示单元测试的基本思想。 实际上,您将必须编写许多测试用例,将它们添加到测试套件中,然后一起运行它们。 测试用例管理将在下一篇文章中讨论。

今天,我们将专注于测试后端。 也就是说,开发人员已根据规范实施了一些项目(例如Calculator.py),而您的任务是确保开发的代码确实与它们匹配(例如,使用TestCalculator.py )。

假设您编写了Calculator类来执行基本的计算功能:加,减,乘和除。

此代码在此处( Calculator.py ):

 #A simple calculator class Calculator: #empty constructor def __init__(self): pass #add method - given two numbers, return the addition def add(self, x1, x2): return x1 + x2 #multiply method - given two numbers, return the #multiplication of the two def multiply(self, x1, x2): return x1 * x2 #subtract method - given two numbers, return the value #of first value minus the second def subtract(self, x1, x2): return x1 - x2 #divide method - given two numbers, return the value #of first value divided by the second def divide(self, x1, x2): if x2 != 0: return x1/x2 

现在,我想运行一个单元测试,以了解上述类中的功能按计划工作。

Python通常随附unittest软件包。 如果它不在您的系统上,请使用pip进行安装。

单元测试具有以下结构:



setUp()tearDown()是unittest框架随附的标准方法(它们在unittest.TestCase类中定义)。 根据您的测试用例,默认情况下您可以覆盖或不覆盖这两种方法。

现在该来看一下测试用例的代码了。 这是文件TestCalculator.py

 import unittest from Calculator import Calculator #Test cases to test Calulator methods #You always create a child class derived from unittest.TestCase class TestCalculator(unittest.TestCase): #setUp method is overridden from the parent class TestCase def setUp(self): self.calculator = Calculator() #Each test method starts with the keyword test_ def test_add(self): self.assertEqual(self.calculator.add(4,7), 11) def test_subtract(self): self.assertEqual(self.calculator.subtract(10,5), 5) def test_multiply(self): self.assertEqual(self.calculator.multiply(3,7), 21) def test_divide(self): self.assertEqual(self.calculator.divide(10,2), 5) # Executing the tests in the above test case class if __name__ == "__main__": unittest.main() 

尽管这不是必需的,但通常我会以前缀Test(在我们的例子中为TestCalculator)调用测试类。 此类的一个关键要求是unittest.TestCase超类的存在。

每当执行此测试用例时,都会首先执行setUp()方法。 在我们的例子中,我们只创建了Calculator类的一个对象,并将其保存为该类的一个属性。 父类中还有其他几种默认方法,我们将在后面讨论。

现在,您要做的就是编写test_xxx方法来测试Calculator类中的每个方法。 请注意,所有测试方法test_前缀test_ 。 这告诉使用unittest框架的Python这些是测试方法。

在每种测试方法中,我都使用内置的assertEqual方法来检查计算器方法是否返回期望值。 如果返回值等于期望值,则测试成功,否则失败。

有许多内置的assert方法,我们将在后面讨论。

上面代码的最后一行只是启动TestCalculator测试用例。 它执行在类中定义的每个测试方法并返回结果。

 python TestCalculator.py -v 


您将看到类似于以下内容的结论:

 test_add (__main__.TestCalculator) ... ok test_divide (__main__.TestCalculator) ... ok test_multiply (__main__.TestCalculator) ... ok test_subtract (__main__.TestCalculator) ... ok -------------------------------------------------------------------- Ran 4 tests in 0.000s OK 

如果某些东西无法按预期工作怎么办? 让我们将test_divide从5更改为6(5是正确的值,现在我们将看到失败的情况。这不是源代码中的错误,而是测试套件中的错误,您可能在测试套件中也有错误,因此请始终检查测试脚本中的错误!)

 import unittest from Calculator import Calculator #Test cases to test Calulator methods #You always create a child class derived from unittest.TestCase class class TestCalculator(unittest.TestCase): #setUp method overridden from the parent class TestCase def setUp(self): self.calculator = Calculator() ... def test_divide(self): self.assertEqual(self.calculator.divide(10,2), 6) # Executing the tests in the above test case class if __name__ == "__main__": unittest.main() 

运行此测试用例时,将得到以下结果:

 test_add (__main__.TestCalculator) ... ok test_divide (__main__.TestCalculator) ... FAIL test_multiply (__main__.TestCalculator) ... ok test_subtract (__main__.TestCalculator) ... ok ==================================================================== FAIL: test_divide (__main__.TestCalculator) -------------------------------------------------------------------- Traceback (most recent call last): File "TestCalculator.py", line 23, in test_divide self.assertEqual(self.calculator.divide(10,2), 6) AssertionError: 5.0 != 6 -------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=1) 

此处表示4个测试中有3个成功,但1个失败。 在实际情况下,假定您的测试用例是正确的,也就是说,以这种方式,它有助于识别未正确实现的功能。

Source: https://habr.com/ru/post/zh-CN481806/


All Articles