简单说说python单元测试框架---unittest

1-单元测试的概念

单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。

def demo(a,b):
    return a / b 

假设我们有一个方法demo,对于这个方法我们可以简单的进行如下的单元测试:

  1. a , b为 4, 2我们期待输出2
  2. a为1 , b为0,期待输出ZeroDivisionError
  3. a为字符串, b为字符串,则期待输出TypeError

把上面的测试用例放到一个测试模块里,就是一个完整的单元测试。如果单元测试通过,说明我们测试的这个函数能够正常工作。如果单元测试不通过,要么函数有bug,要么测试条件输入不正确,总之,需要修复使单元测试能够通过。

2-单元测试的工作原理

2.1 unittest最核心的四个组件:TestCase,TestSuite,TestRunner,TestFixture:

  1. test fixture为了开展一项或多项测试所需要进行的准备工作
  2. TestCase:一个测试用例是一个独立的测试单元。它检查输入特定的数据时的响应。UnitTest  提供一个基类(TestCase )用于新建测试用例。
  3. test suite: 是一系列的测试用例,或测试套件,或两者皆有(TestSuite也可以嵌套TestSuite)。它用于归档需要一起执行的测试
  4. test runner:一个用于执行和输出测试结果的组件。这个运行器可能使用图形接口、文本接口,或返回一个特定的值表示运行测试的结果。

2.2 工作原理:

  1. 一个TestCase的实例就是一个测试用例。测试用例就是指一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
  2. 而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite
  3. TestLoader是用来加载TestCase到TestSuite中的
  4. TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法
  5. 测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。

 他们之间的关系:整个流程就是首先要写好TestCase,然后由TestLoader (用来加载TestCase到TestSuite中的) 加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中。

3-简单实例

import unittest

class UtMber(unittest.TestCase):

    def setUp(self):
        print ("setUp执行了")

    def test_multiply(self):
        c = 1 * 2
        print("test_multiply")
        self.assertEqual(c, 2)

    def test_add(self):
        c = 1 + 1
        print("test_add")
        self.assertEqual(c, 2)

    # 跳过测试(参数是原因)
    @unittest.skip("我就是想跳过")
    def test_skip(self):
        print("test_skip")
        self.assertEqual(1, 2)

    # 跳过测试(第一个参数是状态(布尔),第二个原因)
    @unittest.skipIf(True, "我也想跳过测试")
    def test_skipif(self):
        print("test_skipif")
        self.assertEqual(1, 2)

    def tearDown(self):
        print ("tearDown执行了")

if __name__ == '__main__':
    unittest.main()

执行结果

setUp执行了
..ss
test_add
tearDown执行了
setUp执行了
test_multiply
----------------------------------------------------------------------
tearDown执行了
Ran 4 tests in 0.000s

OK (skipped=2)

从上面结果我们可以得出结论:

  1. setUp:表示前置条件,它在每一个用例执行之前必须会执行一次 

  2. tearDown:表示释放资源,它在每次用例执行完之后会执行一次

  3. 单元测试必须以test开头,执行顺序与字母顺序有关(test_multiply虽然在前面但是test_add先执行)

  4. unittest.skip,unittest.skipIf可以跳过执行单元测试

4-批量运行测试用例

第一种是通过手动添加,通过unittest.Testsuite来管理用例集,通过addTest添加用例方法,再通过实例化TextTestrunner运行测试

#coding:utf-8
import unittest

class DemoTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print ("setUpClass")
    @classmethod
    def tearDownClass(cls):
        print ("tearDownClass")
    def test_add(self):
        a = 12 + 8
        self.assertEqual(a, 20)
        print ('12+8=',a)
    def test_sub(self):
        b = 3-2
        self.assertEqual(b, 1)
        print ('3-2=',3-2)

if __name__=="__main__":
     #实例化用例集
    suite = unittest.TestSuite() 

    suite.addTest(DemoTest("test_add")) 
    suite.addTest(DemoTest("test_sub")) 
    #实例化运行类
    runner = unittest.TextTestRunner() 
    #运行用例集,会根据添加的用例顺序进行用例的执行
    runner.run(suite) 

第二种是通过自动识别用例的目录对所有的用例进行运行。使用到discover()函数

#coding:utf-8
import unittest
import os

class demoTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print "前置测试条件"
    @classmethod
    def tearDownClass(cls):
        print "结束测试条件"
    def test_add(self):
        a = 12 + 8
        self.assertEqual(a, 20)
        print ('12+8=',a)
    def test_sub(self):
        b = 3-2
        self.assertEqual(b, 1)
        print ('3-2=',3-2)

if __name__=="__main__":
    test_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)))#获取当前工作目录
    #用discover的方法去覆盖所有的测试用例
    # test_dir 要执行的测试用例目录
    # test*表示匹配以test开头的所有.py文件
    # top_level_dir=None 测试模块的顶级目录,没有的话就写None
    discover = unittest.defaultTestLoader.discover(test_dir,pattern="test*.py",top_level_dir=None)
    runner = unittest.TextTestRunner() #实例化runner类
    runner.run(discover) #执行路径中匹配的所有test*.py用例

 5-实际案例

我自己封装了一个单元测试例子,在github上,大家可以参考下。github链接

推荐阅读:
官方文档

单元测试快速入门

注意:unittest比较简单,看前两个链接就可以快速入门,特别第二个

猜你喜欢

转载自blog.csdn.net/lin_keys/article/details/107324043