zoukankan      html  css  js  c++  java
  • python的单元测试unittest(一)

    一、什么是单元测试&单元测试的对象

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

    2.单元测试中最核心的四个概念:test case(测试用例),test suite(测试套件),test runner(测试运行器),test fixture(测试环境数据准备和数据清理或者测试脚手架)

      1)test case:一个testcase的实例就是一个测试用例。测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown

      2)TestSuite:多个测试用例集合在一起。

      3)TestLoader:用来加载TestcaseTestSuite中。

      4)TextTestRunner:用来执行测试用例,其中run(test)会执行TestSuite/TestCase中的run(result)方法。

      5)test fixture:测试用例环境的搭建和销毁

     下图为unittest的静态类图:

             

          综上,整个流程就是首先要写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中。

    二、unittest的初级使用

    1.步骤

        1)导入unittest模块,被测文件或者其中的类

        2)创建一个测试类,被继承unittest.TestCase

        3)重写setUptearDown方法(如果有初始化条件和结束条件)

        4)定义测试函数,函数名以test_开头。测试用例

        5)在函数体中使用断言来判断测试结果是否符合预期结果

        6)调用unittset.main()方法运行测试用例--------无此方法也是可以运行

    2.设置setup和teardown:每次用例执行前都会执行初始化条件和结束条件(如下代码可以看到,两个测试用例执行了两次)

    import unittest
    
    class Test_Math(unittest.TestCase):
    
        #每执行一个用例,都会执行setup()和teardown()方法
        #如果跑所有用例,只运行一次前提条件和结束条件。则用setupclass()和teardownclass()
        def setUp(self):
            print("测试用例执行前的初始化操作========")
    
        def tearDown(self):
            print("测试用例执行完之后的收尾操作=====")
    
    
        def test_addTwoNum_01(self):
            print(5+7)
    
        def test_subTwoNum_02(self):
            print(3-2)
    结果:
    测试用例执行前的初始化操作========
    12
    测试用例执行完之后的收尾操作=====
    测试用例执行前的初始化操作========
    1
    测试用例执行完之后的收尾操作=====

    3.设置setupClass和teardownClass:执行所有测试用例,仅执行一次初始化条件和结束条件(如下代码可以看到,两个测试用例只执行了一次)

    import unittest
    
    class Test_Math(unittest.TestCase):
    
        #如果跑所有用例,只运行一次前提条件和结束条件。则用setupclass()和teardownclass()
        @classmethod
        def setUpClass(cls):
            print("在所有的测试用例执行之前,只执行一次============")
    
        @classmethod
        def tearDownClass(cls):
            print("在所有的测试用例执行之后,只执行一次============")
    
        def test_addTwoNum_01(self):
            print(5+7)
    
        def test_subTwoNum_02(self):
            print(3-2)
    
    #python3中写不写都会执行的
    if __name__ == '__main__':
        unittest.main()

    结果: Testing started at
    22:19 ... 在所有的测试用例执行之前,只执行一次============ 12 1 在所有的测试用例执行之后,只执行一次============

    4.断言Assert----结果对比的函数

    Method

    Checks that

    New In

    assertEqual(a,b):相等

    a == b

    assertNotEqual(a,b)

    a != b

    assertTrue(x)

    bool(x) is True

    assertFalse(x)

    bool(x) is False

    assertIs(a,b)

    a is b:判断是否是同一对象(id(a))

    3.1

    asserNottIs(a,b)

    a is not b

    3.1

    assertIsNone(x)

    x is None

    3.1

    assertIsNotNone(x)

    x is not None

    3.1

    assertIn(a,b):a是否在b

    a in b

    3.1

    assertNotIn(a,b)

    a not in b

    3.1

    assertIsInstance(a,b):实例对象

    isInstance(a,b)

    3.2

    assertNotIsInstance(a,b)

    not isInstance(a,b)

    3.2

        设置断言,当一条测试用例执行失败,不会影响其他测试用例的执行。

    import unittest
    
    class Test_Math(unittest.TestCase):
    
        def setUp(self):
            print("测试用例执行前的初始化操作========")
    
        def tearDown(self):
            print("测试用例执行完之后的收尾操作=====")
    
       #正确的断言
        def test_addTwoNum_01(self):
            sum = 5+7
            print(sum)
            self.assertEqual(12,sum)
       
        #设置错误的断言
        def test_subTwoNum_02(self):
            sub = 3-2
            self.assertEqual(11,sub)
    
    
    if __name__ == '__main__':
        unittest.main()
    #结果---直接打印出来失败的原因
    
    Testing started at 10:14 ...
    测试用例执行前的初始化操作========
    12
    测试用例执行完之后的收尾操作=====
    测试用例执行前的初始化操作========
    测试用例执行完之后的收尾操作=====
    
    Failure
    Traceback (most recent call last):
      File "E:柠檬班pythonpython_APIunittest_lianxi.py", line 22, in test_subTwoNum_02
        self.assertEqual(11,sub)
    AssertionError: 11 != 1

         另外,断言也可以直接写>= = <= 来判断

    def test_addTwoNum_01(self):
            sum = 5+7
            print(sum)
            assert sum >= 10

         写了一个方法,通过unnittest去执行

    #方法文件:Myclass_test.py
    
    class Myclass_test:
    
        def __init__(self,a,b):
            self.a = a
            self.b = b
    
        def sum(self):
            sum = self.a + self.b
            return sum
    
        def sub(self):
            sub = self.a - self.b
            return sub
    
    #单元测试文件:test_Myclass.py
    
    import unittest
    from Myclass_test import Myclass_test
    
    class Test_Myclass(unittest.TestCase):
    
        def setUp(self):
            self.myclass = Myclass_test(12,12)
    
        def test_sum(self):
            sum = self.myclass.sum()
            self.assertEqual(24,sum)
    
        def test_sub(self):
            sub = self.myclass.sub()
            self.assertEqual(0,sub)

    三、unittest的进阶使用

    1、testsuite

          addTest():添加一个测试用例

          addTest([,,]):添加多个测试用例

    #实例化套件对象
    s = unittest.TestSuite() #调用addTest来加载测试用例:类名(‘方法名’)的集合 s.addTest(Test_Myclass1("test_sub"))
    s.addTests([Test_Myclass1("test_sub"),Test_Myclass1("test_sum")]) #实例化TextTestRunner对象 runner
    = unittest.TextTestRunner() #调用run()方法 runner.run(s)

    2.addTest的参数:是一个测试用例的列表

      方式一:类名(‘方法名’)的集合 

      方式二:unittest.TestLoader.discover方法匹配目录下的用例-----用的最多的,测试用例在一个目录下

          discover方法中默认匹配模式是从当前目录下找以test开头的py文件(test*)。测试用例的顺序执行是根据字母a-z,0-9的顺序执行的。

      方式三:unittest.TestLoader.loadTestsFromModule匹配模块中的测试用例

            PSTestLoader类、TestSuite类、TestRunner类需要先实例化再使用

      如下是一个单元测试的实例:

       

    #实例:采用unittest.TestLoader.discover方式加载测试用例。
    #
    #####定义函数:Myclass_test.py class Myclass_test: def __init__(self,a,b): self.a = a self.b = b def sum(self): sum = self.a + self.b return sum def sub(self): sub = self.a - self.b return sub ######定义测试类1:test_Myclass1.py import unittest from my_Unittest.Myclass_test import Myclass_test class Test_Myclass1(unittest.TestCase): def setUp(self): self.myclass = Myclass_test(12,12) def test_sum(self): print("sum_1") sum = self.myclass.sum() self.assertEqual(24,sum) def test_sub(self): print("sub_1") sub = self.myclass.sub() self.assertEqual(0,sub) ######定义测试类2:test_Myclass2.py import unittest from my_Unittest.Myclass_test import Myclass_test class Test_Myclass2(unittest.TestCase): def setUp(self): self.myclass = Myclass_test(1,12) def test_sum(self): print("sum_2") sum = self.myclass.sum() self.assertEqual(13,sum) def test_sub(self): print("sub_2") sub = self.myclass.sub() self.assertEqual(-11,sub) ######主函数的调用:Myclass_main.py import unittest import os #实例化测试套件对象 s = unittest.TestSuite() #实例化TestLoader的对象 loader = unittest.TestLoader() #使用discover()去找一个目录下的所有测试用例的文件,并将返回数据添加到测试套件中。 s.addTests(loader.discover(os.getcwd())) run = unittest.TextTestRunner() run.run(s)

    3.定义的测试类和测试套件写在不同的模块里,为什么?

     

    4.测试报告的生成

     第一种:text文件--写到文件中

    #第一种:unittest自带的方法
    #创建一个文件,以写的方式打开
    import unittest
    from test_Myclass1 import Test_Myclass1


    s = unittest.TestSuite()
    s.addTest(Test_Myclass1("test_sub"))
    s.addTests([Test_Myclass1("test_sub"),Test_Myclass1("test_sum")])
    fs = open("test_run_report.txt","w")
    run = unittest.TextTestRunner(fs)
    run.run(s)

       第二种:html测试报告--HtmlTestRunner.py文件

                    python提供第三方库:HtmlTestRunner

                   官方文档:http://tungwaiyip.info/software/HTMLTestRunner.html(适用python2)

                   然后放到你安装的python安装目录中:Libsite-packages目录下即可。示例如下:D:Python34Libsite-packages

    import unittest
    import os
    from HTMLTestRunnerNew import HTMLTestRunner
    
    #实例化测试套件对象
    s = unittest.TestSuite()
    #实例化TestLoader的对象
    loader = unittest.TestLoader()
    #使用discover()去找一个目录下的所有测试用例的文件,并将返回数据添加到测试套件中。
    s.addTests(loader.discover(os.getcwd()))
    fp = open(os.getcwd() +"/test_report.html","wb")
    runner = HTMLTestRunner(stream=fp,
                            title="测试报告标题",
                            description="测试报告描述信息",
                            tester="测试者")
    runner.run(s)

    四、

  • 相关阅读:
    hive 修复分区、添加二级分区
    hive sql 查询一张表的数据不在另一张表中
    shell 命令 bc linux下的计算器
    shell 命令 grep -v
    shell 命令 -- 漂亮的资源查看命令 htop
    shell 命令 --ps aux | grep
    presto调研和json解析函数的使用
    shell wc -l
    hive 动态分区与混合分区
    ThreadLocal原理分析与使用场景(转)
  • 原文地址:https://www.cnblogs.com/xiaoxiaolvdou/p/9503090.html
Copyright © 2011-2022 走看看