zoukankan      html  css  js  c++  java
  • Python-unittest单元测试

    单元测试

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

    比如对函数abs(),可以编写出以下几个测试用例:

    1. 输入整数时,如11.20.99,期待返回值与输入相同。
    2. 输入负数时,如-1-1.2-0.99,期待返回值与输入相反。
    3. 输入0时,期待返回值为0.
    4. 输入非数值类型,如None[]{},期待抛出TypeError异常。

    把上面的测试用例放到一个测试模块里,就是一个完整的单元测试。

    如果单元测试通过,说明我们测试的这个函数能够正常工作。如果单元测试不通过,要么函数有bug,要么测试条件输入不正确,总之,需要修复使单元测试能够通过。

    当我们修改了一个函数的代码,但是不想让它原有的功能改变,当我们修改后,只需要再跑一遍单元测试。如果通过,说明我们的修改没有影响原有的功能。

    Python中内置了一个单元测试的框架unittest,下面我们通过一个单元测试来执行以下,abs()的测试用例。

    unittest

    继承 unittest.TestCase 就创建了一个测试样例。

    测试脚本abs_test.py中的代码如下:

    import unittest
    
    class TestAbsFunc(unittest.TestCase):
        def test_positive(self):
            self.assertEqual(abs(1), 1)
            self.assertEqual(abs(1.2), 1.2)
            self.assertEqual(abs(0.99), 0.99)
    
        def test_negative(self):
            self.assertEqual(abs(-1), 1)
            self.assertEqual(abs(-1.2), 1.2)
            self.assertEqual(abs(-0.99), 0.99)
            
        def test_zero(self):
            self.assertEqual(abs(0), 0)
            
        def test_nonumber(self):
            with self.assertRaises(TypeError):
                abs(None)
            with self.assertRaises(TypeError):
                abs([])
            with self.assertRaises(TypeError):
                abs({})
    
    
    if __name__ == '__main__':
        unittest.main()
    

    上面代码执行的结果为:

    image-20211015163706963

    从运行结果可以看出:进行了4个测试,测试结果为:OK

    下面来分析一下代码:

    首先我们创建了一个TestAbsFunc类,该类继承自unittest.TestCase。此时这个类就是一个测试类。

    这个类中包含了4个方法,可以看出全都是test开头的,因为test开头的方法被认为是测试方法,执行测试的时候只会执行测试方法,其中有两个方法是例外setUptearDown,后面会介绍它们的作用

    四个以test开头的方法分别对应四种测试用例。由于unittest.TestCase提供了很多内置的条件判断,我们只需要调用这些方法就可以断言输出是否是我们所期望的。最常用的断言就是assertEqual()

    self.assertEqual(abs(1), 1) # 断言函数的返回值是否与1相等
    

    另一种重要的断言就是期待抛出指定类型Error,比如通过abs(None) 来返回None的绝对值,会抛出一个TypeError

    with self.assertRaises(TypeError):
        abs(None)
    

    运行单元测试

    一旦编写好单元测试,我们就可以运行单元测试。最简单的运行方式是在测试类的最后加上两行代码:

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

    这样就可以把abs_test.py当做正常的python脚本运行:

    $ python mydict_test.py
    

    另一种方法是在命令行通过参数-m unittest直接运行单元测试:

    $ python -m unittest abs_test
    

    image-20211015164320135

    setUp 和 tearDown

    可以在单元测试中编写两个特殊的setUp()tearDown()方法。这两个方法会分别在每调用一个测试方法的前后分别被执行。

    setUp()tearDown()方法有什么用呢?设想你的测试需要启动一个数据库,这时,就可以在setUp()方法中连接数据库,在tearDown()方法中关闭数据库,这样,不必在每个测试方法中重复相同的代码,在TestAbsFunc 中添加这两个方法:

    def setUp(self):
        print('setUp...')
    
    def tearDown(self):
    	print('tearDown...')
    

    image-20211015165024983

    unittest命令选项

    -b, --buffer

    在测试运行时,标准输出流与标准错误流会被放入缓冲区。成功的测试的运行时输出会被丢弃;测试不通过时,测试运行中的输出会正常显示,错误会被加入到测试失败信息。

    -f, --failfast

    当出现第一个错误或者失败时,停止运行测试。

    -v

    获取更详细(更多的冗余)的信息。

    本文来自博客园,作者:雨-铃,原文链接:https://www.cnblogs.com/yuling25/p/unittest.html

  • 相关阅读:
    Android 进程生命周期 Process Lifecycle
    .NET Core微服务之基于IdentityServer建立授权与验证服务(续)
    .NET Core微服务之基于IdentityServer建立授权与验证服务
    .NET Core微服务之基于Ocelot实现API网关服务(续)
    .NET Core微服务之基于Ocelot实现API网关服务
    .NET Core微服务之基于Polly+AspectCore实现熔断与降级机制
    .NET Core微服务之基于Consul实现服务治理(续)
    .NET Core微服务之基于Consul实现服务治理
    一朝入梦,终生不醒:再看红楼梦,也谈石头记
    月光下的凤尾竹—彩云之南西双版纳游记
  • 原文地址:https://www.cnblogs.com/yuling25/p/unittest.html
Copyright © 2011-2022 走看看