python单元测试模块unittest的接口测试总结

目录

模块定义

python代码批量生成的测试用例所包含的方法

unittest模块组织并执行上述用例的关键方法

接口自动化测试时的注意事项

HTML测试报告相关

参考


模块定义

  • unittest是python自带的单元测试框架。
  • 要使用unittest模块就需要明确什么样的测试用例才能被unittest组织并执行,下面依次进行介绍。

python代码批量生成的测试用例所包含的方法

  • 比如在python实现的接口自动化测试过程中,通过python代码批量生成测试用例类(继承unittest.TestCase),在类中实现以test开头的测试用例方法,一个测试用例类可以包含多个test开头的测试用例方法,然后再通过unittest模块的关键方法实现组织测试用例批量执行、断言并生成测试结果。以下列出完整的一个测试类包含的方法:
    • class PushOrder(unittest.TestCase) ,生成一个类并继承unittest.TestCase
    • def setUp(self) ,用于在每个用例执行前做初始化工作,如连接数据库、加载EXCEL等。一条用例执行一次,多条用例执行多次。
    • def tearDown(self) 用于执行完测试用例后的收尾工作,比如断开数据库连接,关闭文件等。一条用例执行一次,多条用例执行多次。
    • def test_pushOrder(self), 在这个方法中完成了请求入参的拼接、请求的触发、根据检查点对响应结果做校验、响应结果的存储、依赖数据的存储、执行结果的写入等。
    • 注,测试固件setUp和tearDown每次执行用例都会重新执行,如果想更高效可以使用类方法,可以用类方法setUpClass()在所有用例执行前就一次性的准备好环境,用类方法tearDownClass()所有用例执行完后再清理环境。
      • ...
        
        class ApushOrder(unittest.TestCase):
            """ApushOrder"""
        
            @classmethod
            def setUpClass(cls):
                print "This setUpClass() method only called once."
        
            @classmethod
            def tearDownClass(cls):
                print "This tearDownClass() method only called once too."
        
        ...
  • unittest会自动识别test开头的方法为测试代码,不以test开头的方法不会被unittest组织并执行。
  • unittest对test开头的测试用例方法的相关装饰器包括:
    • @unittest.skip(reason) 不执行该用例,跳过。
    • @unittest.skipif(condition, reason) 条件为真跳过该用例。
    • @unittest.skipUnless(condition, reason) 条件为假跳过该用例。
    • @unittest.expectedFailure 将测试用例标记为“预期失败”。
    • @unittest.SkipTest(resaon) 跳过测试方法,可以在测试方法或者setUp()中调用该方法。

unittest模块组织并执行上述用例的关键方法

  • 主要流程就是加载测试用例->把测试用例加入到测试套件中->通过runner执行测试套件。
  • Unittest.TestLoader()、Unittest.TestSuit()、Unittest.TextTestRunner()。
  • Unittest.TestLoader()加载测试用例类,加载测试用例相关方法:
    • loadTestsFromTestCase()
      • testcase = unittest.TestLoader().loadTestsFromTestCase(testCaseClass),testCaseClass即PushOrder类,这里的类必须是Unittest.TestCsse的子类。
    • loadTestsFromModule()
      • testcase = unittest.TestLoader().loadTestsFromModule(module, pattern=None),module是测试用例所在的模块。
    • loadTestsFromName()
      • testcase = unittest.TestLoader().loadTestsFromName(name, module=None),name是测试用例的方法名,使用的格式是'modlue.class.method'。
    • loadTestsFromNames()
      • testcase = unittest.TestLoader().loadTestsFromNames(),括号中是用例列表,使用的格式是['modlue.class.method','modlue.class.method',...]。
    • discover(start_dir被测试模块所在目录, pattern正则匹配要执行的测试用例文件, top_level_dirt测试模块的顶层目录,默认为None)
      • discover = unittest.TestLoader().discover('./script', pattern='*_test.py'), *_test.py根据自动生成的文件名来处理。
      • runner = unittest.TextTestRunner()
      • runner.run(discover )
      • 该方法相当于直接形成了测试套件,所以实现后可以直接通过runner去运行。
  • Unittest.TestSuit()测试套件类,来组织所有测试用例,生成suite对象后调用的相关方法包括:
    • addTests(), 参数可以是列表list或者元组tuple。
      • suite = unittest.TestSuite()
      • suite.addTests(map(PushOrder,['test_pushOrder1','test_pushOrder2' ]))
    • addTest()
      • suite = unittest.TestSuite()
      • suite.addTest(testcase),如果想单个调用测试用例,也可以通过以下写法将测试用例加入到测试套件中:
        • suite.addTest(PushOrder('test_pushOrder1'))
        • suite.addTest(PushOrder('test_pushOrder2'))
  • Unittest.TextTestRunner()测试执行器类,生成runner对象后调用run()方法执行上面通过testsuit组织好的测试套件suite,相关方法:
    • runner = unittest.TextTestRunner()
    • runner.run(suite)
  • Unittest.main()可以实现单独执行所在的测试用例类,具体体现为:
    # encoding = utf-8
    import unittest, requests
    from utils.operate_excel import *
    from utils.db_handler import *
    import os, sys, json
    from utils.ParseExcel import *
    from interface.create_script1 import *
    from utils.LogInfo import *
    
    
    class ApushOrder (unittest.TestCase):
        def setUp(self):
            XXXX
        def test_pushOrder1(self):
            XXXX
        def tearDown(self):
            XXXX
    
    
    if __name__ == '__main__':
        unittest.main()
  • 断言,Unittest的断言方法包括如下
    • assertEqual(a,b,msg) a等于b则测试通过
    • assertIsInstance(a,b,msg) a属于b类型则测试通过
    • assertIn(a,b,msg) a包含于b中则测试通过
    • assertTrue(a,msg) a为真则测试通过
    • assertNone(a.msg) a为None则测试通过

接口自动化测试时的注意事项

  • 生成的一个*_test.py的测试用例文件,里面包含一个接口的多个用例的执行顺序。
    • 一个测试类中依次实现了三条测试用例test_zpushOrder1, test_bpushOrder2, test_apushOrder3,可以在该文件下直接通过unittest框架unittest.main()执行,执行后会发现这三条用例的执行顺序是随机的,并不是按照编写顺序执行(unittest.main()相当于调用TextTestRunner中的run来执行)。
    • 用例的执行顺序不是按照编写顺序,执行顺序是按照ASCII码的顺序加载执行,数字与字母的顺序为0-9, A-Z,a-z,即test_pushOrder1会比test_pushOrder3先执行,所以在同一个接口的.py文件中可以通过这个规则来规定用例执行顺序。
    • 如果一个接口类文件A_test.py里有三条用例,需有先后执行顺序的话,可以按照执行规则来命名用例名,如test_aorder,test_border,test_corder后运行。也可以通过TestSuite来处理,测试用例会按照添加顺序执行,可以通过addTests添加用例列表,也可以通过addTest逐个添加用例,比如:
      • suite = unittest.TestSuite()
        tests = [ApushOrder("test_zpushOrder1"),ApushOrder("test_bpushOrder2"), ApushOrder("test_apushOrder3")]
        suite.addTests(tests)
        # 上两句就相当于 suite.addTests(map(PushOrder,['test_pushOrder1','test_pushOrder3' ,'test_pushOrder2'])) 
        runner = unittest.TextTestRunner(verbosity=2)
        runner.run(suite)
  • 比如有三个接口需要做接口自动化测试A,B,C,通过python代码批量生成的三个*_test.py的测试用例文件,叫A_test.py、B_test.py、C_test.py,这三个接口是有前后关联关系的,即A-B-C,每个接口有若干条测试用例,A有3条用例,B有1条用例,C有2条用例。如何通过unittest去组织接口用例并执行。
    • 仍然通过TestSuite实现,可以通过addTests添加用例列表,也可以通过addTest逐个添加用例,比如:
      suite = unittest.TestSuite()
      tests = [ApushOrder("test_zpushOrder1"),ApushOrder("test_bpushOrder2"), ApushOrder("test_apushOrder3"), BrepayPlan("test_repayPlan1"),CpreRepayment("test_1preRepaymentTrial"),CpreRepayment("test_2preRepaymentApply")]
      suite.addTests(tests)
      runner = unittest.TextTestRunner(verbosity=2)
      runner.run(suite)
  • 如果不需要考虑执行顺序问题,还可以通过TestLoader方法来加载测试用例,如最上方绿色字体相关的代码。
    • testcase = unittest.TestLoader().loadTestsFromTestCase(testCaseClass) 即批量生成的.py文件的模块下的类名
    • testcase = unittest.TestLoader().loadTestsFromName('ApushOrder_test.ApushOrder') 即批量生成的.py文件的模块名.类名
    • testcase = unittest.TestLoader().loadTestsFromNames(['ApushOrder_test.ApushOrder','BrepayPlan_test.BrepayPlan','CpreRepayment_test.CpreRepayment'])
    • suite = unittest.TestSuite()
    • suite.addTest(testcase)
  • TestSuit还可以套TestSuit。

HTML测试报告相关

  • 通过HTMLTestRunner.py文件可以将测试结果以.html的方式展示,使测试结果更加清晰。该文件可以网上下载,但是使用前要确认下载是python2语法还是python3语法,如果和当前使用的python版本不一致需要修改部分代码。
    • 相关代码和执行结果,verbosity控制结果的输出,0是简单报告,1是一般报告,2是详细报告。
    • # -*- coding:utf-8 -*-
      # author:Chang JinLing
      # datetime:2021/2/23 10:49
      import sys
      import unittest
      sys.path.append("./script")
      from utils.HTMLTestRunner import HTMLTestRunner # 生成测试报告
      import time
      from script.ApushOrder_test import ApushOrder
      from script.BrepayPlan_test import BrepayPlan
      from script.CpreRepayment_test import CpreRepayment
      
      if __name__ == "__main__":
          suite = unittest.TestSuite()
          tests = [ApushOrder("test_pushOrder1"), ApushOrder("test_pushOrder2"), ApushOrder("test_pushOrder3"),
                   BrepayPlan("test_repayPlan1"), CpreRepayment("test_1preRepaymentTrial"), CpreRepayment("test_2preRepaymentApply")]
          suite.addTests(tests)
          now = time.strftime("%Y-%m-%d %H_%M_%S")
          filename = './report/' + now + '_result.html'
          fp = open(filename, "wb")
          runner = HTMLTestRunner(stream=fp, title="接口自动化测试", description="接口自动化测试结果报告", verbosity=2)
          runner.run(suite)
          fp.close()
  • 如果只是想简单的输出测试结果也可以通过输出.txt文件来展示。
    • 相关代码和执行结果
    • # -*- coding:utf-8 -*-
      # author:Chang JinLing
      # datetime:2021/2/23 10:49
      import sys
      import unittest
      sys.path.append("./script")
      import time
      from script.ApushOrder_test import ApushOrder
      from script.BrepayPlan_test import BrepayPlan
      from script.CpreRepayment_test import CpreRepayment
      
      if __name__ == "__main__":
          suite = unittest.TestSuite()
          tests = [ApushOrder("test_pushOrder1"), ApushOrder("test_pushOrder2"), ApushOrder("test_pushOrder3"),
                   BrepayPlan("test_repayPlan1"), CpreRepayment("test_1preRepaymentTrial"), CpreRepayment("test_2preRepaymentApply")]
          suite.addTests(tests)
          with open('UnittestTextReport.txt', 'a') as f:
              runner = unittest.TextTestRunner(stream=f, verbosity=2)
              runner.run(suite)
          f.close()

 

参考

https://www.cnblogs.com/billie52707/p/13069984.html

https://www.cnblogs.com/yufeihlf/p/5707929.html

猜你喜欢

转载自blog.csdn.net/chang_jinling/article/details/113986771