Selenium实战(四)——unittest单元测试框架1
Python中的单元测试框架包含:doctest、unittest、pyttest、nose等,使用unittest单元测试框架不需要自行定义断言失败的提示,并且当一个测试函数执行失败后,后面的测试函数还会继续执行下去。下面以一个简单计算器来编写自动化测试用例。被测试的代码如下:
1 # 计算器类 2 class Calculator: 3 def __init__(self, a, b): 4 self.a = int(a) 5 self.b = int(b) 6 7 def add(self): 8 return self.a + self.b 9 10 def sub(self): 11 return self.a - self.b 12 13 def mul(self): 14 return self.a * self.b 15 16 def div(self): 17 return self.a / self.b
通过unittest单元测试框架编写如下测试用例:
1 import unittest 2 3 from files.unit_test.calculator import Calculator 4 5 6 class TestCalculator(unittest.TestCase): 7 def test_add(self): 8 c = Calculator(3, 5) 9 result = c.add() 10 self.assertEqual(result, 8) 11 12 def test_sub(self): 13 c = Calculator(10, 5) 14 result = c.sub() 15 self.assertEqual(result, 5) 16 17 def test_mul(self): 18 c = Calculator(5, 7) 19 result = c.mul() 20 self.assertEqual(result, 34) 21 22 def test_div(self): 23 c = Calculator(12, 6) 24 result = c.div() 25 self.assertEqual(result, 2) 26 27 28 if __name__ == '__main__': 29 unittest.main()
执行结果展示:
一、使用unittest单元测试框架的规则
1.创建一个测试类(TestCalculator),该类必须继承unittest模块的TestCase类;
2.创建的测试方法必须以test开头。
通过unittest提供的assertEqual()方法来断言结果与预期是否一致,该方法由TestCase父类提供,由于继承了该类,可用self调用。关于测试结果:
(1)“.”表示一条运行通过的测试用例。
(2)“F”表示一条运行失败的测试用例。
(3)“E”表示一条运行错误的测试用例。
(4)“s”表示一条运行跳过的测试用例。
二、重要的概念
1.Test Case
最小的测试单元。用于检查特定输入集合的特定返回值。unittest提供了TestCase基类,脚本中创建的测试类需要继承该基类,用来创建新的测试用例。
2.Test Suit
测试套件是测试用例、测试套件或两者的集合,用于组装一组要运行的测试。
3.Test Runner
是一个组件,用于协调测试的执行并向用户提供结果。可以使用图形界面、文本界面或返回特殊值来展示执行测试的结果。unittest提供了TextTestRunner类运行测试用例,为了生成HTML格式的测试报告,会选择使用HTMLTestRunner运行类。
4.Test Fixture
代表执行一个或多个测试所需的环境准备,以及关联的清理动作。例如,创建临时或者代理数据库、目录,或启动服务器进程。unittest中提供了setUp()/tearDown()、setUpClass()/tearDownClass()等方法来完成这些操作。
基于这四个概念的理解,修改以上测试用例如下:
1 import unittest 2 3 from files.unit_test.calculator import Calculator 4 5 6 class TestCalculator(unittest.TestCase): 7 8 # 测试用例前置动作 9 def setUp(self): 10 print("test start") 11 12 # 测试用例后置动作 13 def tearDown(self): 14 print("test end") 15 16 def test_add(self): 17 c = Calculator(3, 5) 18 result = c.add() 19 self.assertEqual(result, 8) 20 21 def test_sub(self): 22 c = Calculator(10, 5) 23 result = c.sub() 24 self.assertEqual(result, 5) 25 26 def test_mul(self): 27 c = Calculator(5, 7) 28 result = c.mul() 29 self.assertEqual(result, 34) 30 31 def test_div(self): 32 c = Calculator(12, 6) 33 result = c.div() 34 self.assertEqual(result, 2) 35 36 37 if __name__ == '__main__': 38 # 创建测试套件 39 suit = unittest.TestSuite() 40 suit.addTest(TestCalculator("test_add")) 41 suit.addTest(TestCalculator("test_sub")) 42 suit.addTest(TestCalculator("test_mul")) 43 suit.addTest(TestCalculator("test_div")) 44 # 创建测试运行器 45 runner = unittest.TestRunner() 46 runner.run(suit)
在测试用例的执行时,抛弃了unittest提供的main()方法,而是调用了TestSuite类下面的addTest()来添加测试用例。因为一次只能添加一条用例,所以需要指定测试类及测试方法。然后调用TextTestRunner类下面的run()运行测试套件。这样做比直接用main()麻烦,首先,测试用例的执行顺序可以由测试套件的添加顺序控制,而main()方法只能按照测试类、方法的名称来执行测试用例。例如,TestA类比TestB类限制性,test_add()用例比test_div()用例限制性;其次,当一个测试文件中有很多测试用例时,并不是每次都要执行所有的测试用例,尤其是比较耗时的UI自动化测试。因而通过测试套件和测试运行器可以灵活的控制要执行的测试用例。