Unittest框架的从零到壹(二)
四大重要概念
在unittest文档中有四个重要的概念:Test Case、Test Suite、Test Runner和Test Fixture。只有理解了这几个概念,才能理解单元测试的基本特征。
1.Test Case Test Case是最小的测试单元,用于检查特定输入集合的特定返回值。unittest提供了TestCase基类,我们创建的测试类需要继承该基类,它可以用来创建新的测试用例。
2.Test Suite测试套件是测试用例、测试套件或两者的集合,用于组装一组要运行的测试。unittest提供了TestSuite类来创建测试套件。
3.Test Runner Test Runner是一个组件,用于协调测试的执行并向用户提供结果。Test Runner可以使用图形界面、文本界面或返回特殊值来展示执行测试的结果。unittest提供了TextTestRunner类运行测试用例,为了生成HTML格式的测试报告,后面会选择使用HTMLTestRunner运行类。
4.Test Fixture
Test Fixture代表执行一个或多个测试所需的环境准备,以及关联的清理动作。例如,创建临时或代理数据库、目录,或启动服务器进程。unittest中提供了setUp()/tearDown()、setUpClass()/tearDownClass()等方法来完成这些操作。
在理解了上面几个概念之后,我们对前面的测试用例做如下修改。(这里指的是该系列的上一篇文章)
import unittest
from calculator import Calculator
class TestCalculator(unittest.TestCase):
def setUp(self): #Test Fixture-每条用例开始执行前,执行该方法
print("开始执行测试")
def tearDown(self): #Test Fixture-每条用例结束执行后,执行该方法
print("执行测试结束")
def test_add(self):
c = Calculator(1, 2)
result = c.add()
self.assertEqual(result, 3)
def test_sub(self):
c = Calculator(5, 1)
result = c.sub()
self.assertEqual(result, 4)
def test_mul(self):
c = Calculator(5, 1)
result = c.mul()
self.assertEqual(result, 6)
def test_div(self):
c = Calculator(6, 2)
result = c.div()
self.assertEqual(result, 3)
if __name__ == '__main__':
#创建测试套件TestSuite
suit = unittest.TestSuite()
suit.addTest(TestCalculator("test_add"))
suit.addTest(TestCalculator("test_sub"))
suit.addTest(TestCalculator("test_mul"))
suit.addTest(TestCalculator("test_div"))
#创建测试运行期TestRunner
runner = unittest.TextTestRunner()
runner.run(suit)
这里需要特别说明的就是,抛弃了unittest提供的main()方法,而是调用TestSuite类下面的addTest()来添加测试用例。再将Testsuite放入TestRunner里面进行启动。
这里做一个形象的比喻,TestRunner相当于枪的扳机,Testsuite相当于枪的弹夹,每一个TestCase(测试方法)就相当于子弹,而TestFixtrue则是开枪前和开枪后的动作。每执行一次测试方法都是射出了一发子弹🙊
有同学会问,为什么需要用到这些,我之前不做这些不也能开枪(执行测试用例)吗?
这样做确实比直接使用main()方法要麻烦得多,但也并非没有优点。
-
首先,测试用例的执行顺序可以由测试套件的添加顺序控制,而main()方法只能按照测试类、方法的名称来执行测试用例。例如,TestA类比TestB类先执行,test_add()用例比test_div()用例先执行。
-
其次,当一个测试文件中有很多测试用例时,并不是每次都要执行所有的测试用例,尤其是比较耗时的U自动化测试。因而通过测试套件和测试运行器可以灵活地控制要执行的测试用例。
不过一个一个地添加测试用例到测试套件中,有点麻烦,所以可以把要执行的测试用例用个列表来管理,然后再把这个列表添加到测试套件中
if __name__ == "__main__":
# 构造测试套件
suite = unittest.TestSuite()
test_cases = [TestCalculator("test_add"),TestCalculator("test_sub"),TestCalculator("test_div")]
suite.addTests(test_cases)
# 执行测试
runner = unittest.TextTestRunner(verbosity=2) #verbosity 参数可以控制输出的错误报告的详细程度,默认是 1;如果设为 0,则不输出每一用例的执行结果;如果设为 2,则输出详细的执行结果
runner.run(suite)
ok,这一篇就是为了简单介绍四个重要概念,下一篇来讲关于unittest其他还需要知道/注意的点。