zoukankan      html  css  js  c++  java
  • 单元测试unittest(基于数据驱动的框架:unittest+HTMLTestRunner/BeautifulReport+yaml+ddt)

    一、定义

    unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果。

    unittest通过建立类并继承父类unittest.TestCase将用例组织起来,统一执行

    示例:

    import unittest
    class Testcase(unittest.TestCase):#类继承unittest.TestCase
        def setUp(self):#每条用例运行前,运行。一般可用来做些准备工作
            print('我是setup,什么时候运行')
    
        def tearDown(self):#每条用例结束后,运行,一般可用来做些收尾工作
            print('teardown什么时候运行')
        def testa(self):
            print('测试用例a')
            self.assertEqual(1,2,'计算结果不正确')
            #assertEqual是父类unittest.TestCase的函数,用来验证实际结果是否与预期结果相等
           #第一个参数是预期结果,第二个参数是实际结果,第三个参数是当前面两个不相等时,回显示的提示信息。第三个参数是非必填的
        def testb(self):
            '''这里是测试用例的描述,会最终显示在测试报告中的,必须用三个单引号括起来才可以,用#d不行'''
            print('测试用例b')
            self.assertEqual(1,1)
        def c(self):
            print('c函数不是以test开头的,所以不会当做用例被执行')
            # self.assertIn('a','abc')
        @classmethod
        def setUpClass(cls):#所有的用例运行前,运行setupClass
            print('什么时候运行setupClass')
        def tearDownClass(cls):#所有用例运行后,执行tearDownClass
            print('什么时候运行tearDownClass')
    
    unittest.main()#执行当前python文件中的所有用例,会在控制台显示运行结果,不会产生测试报告
    #运行的时候不要右键运行run unittest for...,这个是pycharm自己给运行的unittest,不会产生测试报告
    # 应点击菜单栏中Run--run,弹出提示框后,选择自己要运行的文件进行run
    #函数名用例必须以test开头,才会被执行

    二、用例集suite+HTMLTestRunner/BeautifulReport

    用例集即测试套件,可以吧所有的用例放入用例集当中执行,并结合HTMLTestRunner或者BeautifulReport产生出直观的漂亮的测试报告

    #-------------------------------------------------------------------HTMLTestRunner写报告(丑)
    #将下载好的HTMLTestRunner.py 放到 pycharm的External Libraries目录下的lib目录下,然后导入:import HTMLTestRunner,紧接着上面的代码:(把unittest.main注释掉)

    suite=unittest.TestSuite()#定义用例集,是个list
    suite.addTest(unittest.makeSuite(Testcase))#将类TestCase先变成一个用例集合,然后再加入到suite中
    f=open('测试报告.html','wb')#建立一个测试报告文件
    runner=HTMLTestRunner.HTMLTestRunner(f,title='测试报告标题',description='测试报告描述')#title和decription都是非必填。将用例结果写入测试报告.html
    runner.run(suite)#运行用例集,用例执行的顺序是按照字母排序的

    然后通过run-run选中要执行的当前文件,运行后,就会产生一个html格式的报告,可用浏览器打开,如下:

    #--------------------------------------------------------BeautifulReport 报告(美)

    #下载BeautifulReport ,解压后运行setup.py。可以将解压后的文件拷贝到pycharm中,然后运行setup.py也可。然后要导入:

    from BeautifulReport import BeautifulReport as bf #bf就是个别名,方便使用

    suite=unittest.TestSuite()#定义用例集,是个list
    suite.addTest(unittest.makeSuite(Testcase))#将类TestCase先变成一个用例集合,然后再加入到suite中
    report=bf(suite)##先实例化这个类
    report.report(description='用例描述',filename='用例文件名字')
    #description必填参数,log_path是非必写的,默认在当前目录下。也可以定义别的目录
    #filename可写可不写,回自动生成个名字。名字后缀默认就是html。可写上也可不写

    执行后,生成html格式报告:打开:

     三、用unittest测接口示例

    1、接口数据:yaml格式文件,存有3条用例数据

    2、用ddt自动读取用例数据并传递给测试类中的测试用例函数

    3、执行用例

    4、写报告

    用例数据

    - #用减号-区分不同的用例。最终是个list,然后每个list是个字典:  [{}{}]
      url: /api/user/login
      detail: 正常登录
      method: post
      data:
        username: aaa
        passwd: aA123456
      check:
        - userId
        - error_code
    
    -
      url: /api/user/login
      detail: 密码错误
      method: post
      data:
        username: aaa
        passwd: aA1234
      check:
        - 密码错误
    
    -
      url: /api/user/login
      detail: 必填参数未填,用户名不传
      method: post
      data:
        passwd: aA1234
      check:
        - 必填参数未填

    接口测试代码:获取数据,执行测试用例并发送测试结果报告

    import unittest
    import  ddt#自动读取文件内容,该模块需要先安装pip install ddt
    import requests
    from BeautifulReport import BeautifulReport as bf
    from urllib import parse
    
    
    @ddt.ddt #声明这个类要用ddt
    class Login(unittest.TestCase):
        base_url='http://100.20.20.40'
        @ddt.file_data('login1.yaml')#ddt自动读取文件,并获取内容传给下面的函数,循环调用.运行如果出现字符编码问题,就直接打开file_data源文件,搜索open,将打开文件的代码中,加上encoding=utf-8
        def test_request(self,**kwargs):#**kwargs可以传入字典参数,不限个数.此处用来接收从login1.yaml中读出来的用例,是字典
            detail=kwargs.get('detail','没写用例描述')#如果没有定义detail,默认给个值’没写用例描述‘
            self._testMethodDoc=detail#设置用例描述
    
            url=kwargs.get('url')
            url=parse.urljoin(self.base_url,url)#自动拼接url,
            method=kwargs.get('method','get')#method默认给个get方法
            data=kwargs.get('data',{})#如果没给data,默认给个空字典
            header=kwargs.get('header',{})#如果没有header参数,默认给个空字典
            cookie=kwargs.get('cookie',{})
            check=kwargs.get('check')#获取login1.yaml中的预期结果check,是list
            method=method.lower()#
            try:
                if method=='get':
                    res=requests.get(url,params=data,cookies=cookie,headers=header).text
                    #因为实际结果失败的话,不会返回json串,所以不能转成字典
                else:
                    res=requests.post(url,data,cookies=cookie,headers=header).text
            except Exception as e:
                print('接口请求出错')
                res=e
            for c in check:#循环遍历check中的所有预期结果,判断是否包含在实际结果中
                self.assertIn(c,res,msg='预期结果不符,预期结果%s,实际结果%s'%(c,res))#断言,如果预期结果在实际结果中,pass.否则断言失败并给出错误信息msg
    
    suite=unittest.TestSuite()
    suite.addTest(unittest.makeSuite(Login))
    run=bf(suite)
    run.report('login_test','登录测试用例')#第一个是描述,第二个是文件名
    print(run.success_count)#通过的次数
    print(run.failure_count)#失败次数)
  • 相关阅读:
    解决使用git出现 The file will have its original line endings in your working directory
    SpringBoot集成flowable碰见DMN不能初始化
    CF268D Wall Bars
    CF1327F AND Segments
    P2900 [USACO08MAR]Land Acquisition G
    CF279B Books
    CF859E Desk Disorder
    CF1147B Chladni Figure
    CF1147E Rainbow Coins
    P3565 [POI2014]HOT-Hotels
  • 原文地址:https://www.cnblogs.com/bendouyao/p/9153557.html
Copyright © 2011-2022 走看看