python单元测试框架—unittest

目录

unittest核心工作原理

unittest示例

示例1:简单示例

示例2:setUpClass()和tearDownClass()

示例3:通过在测试用例方法名中添加数字test_N指定执行顺序

示例4:skip跳过测试用例执行的3种方式

示例5:组织TestSuite

示例6:assert断言

断言方法说明

示例7:输出HTML报告

示例8:第一个webDriver测试

示例9:ddt数据驱动


unittest核心工作原理

转载于文章Python必会的单元测试框架 —— unittest

unittest中最核心的四个概念是:test case, test suite, test runner, test fixture

  •  一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。单元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
  • 而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
  • TestLoader是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
  • TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
  • 测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
  • 而对一个测试用例环境的搭建和销毁,是一个Fixture

一个class继承了unittest.TestCase,便是一个测试用例,但如果其中有多个以 test 开头的方法,那么每有一个这样的方法,在load的时候便会生成一个TestCase实例,如:一个class中有四个test_xxx方法,最后在load到suite中时也有四个测试用例。

到这里整个流程就清楚了:

写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,我们通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者我们可以直接通过TextTestRunner来执行用例。这里加个说明,在Runner执行时,默认将执行结果输出到控制台,我们可以设置其输出到文件,在文件中查看结果(你可能听说过HTMLTestRunner,是的,通过它可以将结果输出到HTML中,生成漂亮的报告,它跟TextTestRunner是一样的,从名字就能看出来)。

unittest示例

示例1:简单示例

#encoding=utf-8
import unittest
import random
class TestSequenceFunctions(unittest.TestCase):
    def setUp(self):
        # 初始化一个递增序列
        self.seq = list(range(10))
        print ("setup completed!")

    def test_run(self):
        # 从序列seq中随机选取一个元素
        element = random.choice(self.seq)
        # 验证随机元素确实属于列表中
        self.assertTrue(element in self.seq)
		
    def test_sth(self):
        assert 1==2
		
    def tearDown(self):
        print ("tearDown completed")
		
class TestDictValueFormatFunctions(unittest.TestCase):
    def setUp(self):
        self.seq = list(range(10))
        print("setup is ready!")

    def test_shuffle(self):
        # 随机打乱原seq的顺序
        random.shuffle(self.seq)
        self.seq.sort()
        self.assertEqual(self.seq, list(range(10)))
        # 验证执行函数时抛出了TypeError异常
        self.assertRaises(TypeError, random.shuffle, (1, 2, 3))

    def tearDown(self):
        print ("tearDown is Done!")

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

执行结果: 

setup is ready!
tearDown is Done!
.setup completed!
tearDown completed
.setup completed!
tearDown completed
F
======================================================================
FAIL: test_sth (__main__.TestSequenceFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "F:\unittest\e1_unittest_demo.py", line 17, in test_sth
    assert 1==2
AssertionError

----------------------------------------------------------------------
Ran 3 tests in 0.027s

FAILED (failures=1)

说明:

  • 可以看到一共运行了3个测试用例,2个成功,1个失败,并给出失败原因:1==2
  • 每一个用例执行的结果的标识,成功是 .,失败是 F,出错是 E,跳过是 S
  • setUp()和tearDown()分别执行了3次,在每个测试用例执行前后分别执行了setUp和tearDown方法
  • 每个测试方法均以 test 开头,否则是不被unittest识别的
  • 可以看到测试的执行跟方法写的位置顺序没有关系,测试用例的默认执行顺序是根据用例名的字母顺序来的,先执行了TestDictValueFormatFunctions类中的test_shuffle,然后执行了TestSequenceFunctions类中的test_run,最后执行了TestSequenceFunctions中类的test_sth

示例2:setUpClass()和tearDownClass()

#encoding=utf-8
import unittest

# 被测试类
class myclass(object):
    @classmethod
    def sum(self, a, b):
        return a + b #将两个传入参数进行相加操作

    @classmethod
    def sub(self, a, b):
        return a - b #将两个传入参数进行相减操作


class mytest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):#每个测试类的setUpClass方法,只会执行一次
        "初始化类固件"
        print ( "----setUpClass")

    @classmethod
    def tearDownClass(cls):#每个测试类的tearDownClass方法,只会执行一次
        "重构类固件"
        print ( "----tearDownClass")

    # 初始化工作
    def setUp(self):#每个测试方法均会执行一次
        self.a = 3
        self.b = 1
        print ( "--setUp")

    # 退出清理工作
    def tearDown(self):#每个测试方法均会执行一次
        print ( "--tearDown")

    # 具体的测试用例,一定要以test开头
    def testsum(self):
        # 断言两数之和的结果是否是4
        self.assertEqual(myclass.sum(self.a, self.b), 4, 'test sum fail')

    def testsub(self):
        # 断言两数之差的结果是否是2
        self.assertEqual(myclass.sub(self.a, self.b), 2, 'test sub fail')


if __name__ == '__main__':
    unittest.main() # 启动单元测试

执行结果:

----setUpClass
--setUp
--tearDown
.--setUp
--tearDown
.----tearDownClass

----------------------------------------------------------------------
Ran 2 tests in 0.011s

OK

说明:

setUpClass()tearDownClass()分别在每个测试类执行前后各执行一次(不管这个测试类中有多少个测试方法,它们都仅执行一次);而setUp()和tearDown()分别在每个测试方法执行前后各执行一次。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值