Unittest单元测试框架基础知识(下)

发表于:2022-7-19 09:16

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:www_pu    来源:51CTO博客

  四、unittest结合ddt模块 给测试用例传参
  unittest 和 ddt 有很好的契合度,ddt读取的数据可以直接用于unittest。
  4.1 ddt.data直接传参
  import unittest # python自带,不需要额外安装
  from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
  from web_key_demo import KeyDemo
  @ddt # 装饰ddt来声明我要用这个ddt来管理测试类
  class CaseDemo(unittest.TestCase):
      # 在测试用例执行前先执行
      def setUp(self) -> None:
          print('+++++++++++++++++++++++++++++++++++')
          pass
      # 测试用例执行后紧接着执行
      def tearDown(self) -> None:
          print('------------------------------------')
          pass
      # ======================================================= ddt的data直接传参 =======================================
      @data('隔壁老王') # 单个传参
      def test_01(self,name):
          print(name)
      @data(['隔壁老赵','嘿咻嘿咻'])  # 多个参数
      @unpack # 多个参数需要这样解压
      def test_02(self, name, action):
          print(name)
          print(action)
      @data(['隔壁老王', '睡觉'],['隔壁老李', '幽会'])  # 多组数据,每组多个参数,几组数据执行几次函数
      @unpack  # 需要这样解压
      def test_03(self, name, action):
          print(name)
          print(action)
  if __name__ == '__main__':
      unittest.main()
      """
      +++++++++++++++++++++++++++++++++++
  隔壁老王
  ------------------------------------
  +++++++++++++++++++++++++++++++++++
  隔壁老赵
  嘿咻嘿咻
  ------------------------------------
  +++++++++++++++++++++++++++++++++++
  隔壁老王
  睡觉
  ------------------------------------
  +++++++++++++++++++++++++++++++++++
  隔壁老李
  幽会
  ------------------------------------
  Ran 4 tests in 0.013s
  OK
      """
  4.2 ddt模块读取yaml文件
  第三节代码可以发现,测试用例01和02只是数据不同,可以采取数据驱动。
  首先需要安装ddt和PyYAML模块,用ddt读取yaml数据文件中一组一组数据为一个个的字典,逐个传入测试用例来执行。
  import unittest
  from ddt import ddt,file_data
  from web_key_demo import KeyDemo
  @ddt # 装饰ddt来管理测试类
  class CaseDemo(unittest.TestCase):
      # 在测试用例执行前先执行
      def setUp(self) -> None:
          self.kd = KeyDemo('Chrome')
      # 测试用例执行后紧接着执行
      def tearDown(self) -> None:
          self.kd.quit()
      @file_data('./data/search.yaml') # ddt模块读取文件中数据转化为一组一组数据传入测试用例
      def test_01(self, url, _input, click): # 测试用例名字需要以test开头
          self.kd.open(url)
          self.kd.input(**_input)
          self.kd.click(**click)
          self.kd.sleep(3)
  if __name__ == '__main__':
      unittest.main()
  yaml文件 数据层:
  - # 一个符号表示一组数据,ddt读取后是一个字典
    url : http://www.baidu.com
    _input:
      name: id # _input下的一组数据,读取后字典键值对的value是一个字典
      value: kw
      txt: 美女
    click:
      name: id
      value: su
  -
    url : http://www.baidu.com
    _input:
      name: id
      value: kw
      txt: 妹子
    click:
      name: id
      value: su
  -
    url : http://www.jd.com
    _input:
      name: id
      value: key
      txt: 不可描述的好东西
    click:
      name: xpath
      value: //button[@aria-label='搜索']
  search.yaml
  五、测试套件
  测试套件就是测试用例的集合,我们添加什么用例他就包含什么,执行顺序按照添加顺序。
  unittest.main()只能以默认顺序执行所有的测试用例,可以用到测试套件来执行一部分测试用例,并且顺序可以指定。
  注意:测试套件的代码必须另外一个文件,不能直接写在测试用例文件的main内。
  import unittest # python自带,不需要额外安装
  from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
  @ddt # 装饰ddt来声明我要用这个ddt来管理测试类
  class CaseDemo(unittest.TestCase):
      # 如果希望从外边向测试用例类传参,就需要调用父类的init,从源码可以看到父类只有methodName='runTest'这么一个参数
      def __init__(self, methodName='runTest',wechat=None):
          super().__init__(methodName=methodName)
          self.wechat = wechat
      # 在测试用例执行前先执行
      def setUp(self) -> None:
          print('+++++++++++++++++++++++++++++++++++')
      # 测试用例执行后紧接着执行
      def tearDown(self) -> None:
          print('------------------------------------')
      def test_01(self):
          """test_01:注释可以显示在报告的描述信息中
          """
          print('print信息可以显示在成功的用例的测试报告中')
      @data('隔壁老王')  # 单个传参
      def test_03(self, name):
          print(name)
      @unittest.skip('我无条件跳过,就无条件跳过')
      def test_skip1(self):
          """test_skip1:注释可以显示在报告的描述信息中
          """
          print('test_skip1我还有机会BB么??')
      def test_assert(self):
          """'断言测试,msg是断言失败后提示信息,可以不要'
          """
          def _test():
              return '老王'
          res = _test()
          # 各种断言的方法都是内置属性,可以选择合适的来用
          self.assertEqual(res,'老赵', msg=f'不是老赵干的别冤枉他,是{res}干的') # 断言value1 == value2
          # # 失败后返回 AssertionError: '老王' not found in ['老张', '老李'] : 老王不在嫌疑人里面里面,不是他
          # self.assertIn(res,['老张','老李'],msg=f'{res}不在嫌疑人里面里面,不是他')
          # # 失败后返回: '老王' is not false : 返回不是False
          # self.assertFalse(res,msg='返回不是False')
  if __name__ == '__main__':
      unittest.main()
      # # 在这个测试用例的main中这样添加套件,执行后你会发现还是执行了所有,并不是只执行了套件中添加的几个用例
      # # 在测试类的main函数中默认执行unittest.main()方法,套件不会生效,套件必须生成新的对象,即另外建立文件导入CaseDemo类来构建
      # import unittest
      # # 构造测试集
      # suite = unittest.TestSuite()
      # # 添加测试用例
      # suite.addTest(CaseDemo('test_skip1'))
      # suite.addTest(CaseDemo('test_assert'))
      # # suite.addTest(CaseDemo('test_03')) # 这个test_03用了ddt传参,不会运行。。。不知为何
      # # 执行测试
      # runner = unittest.TextTestRunner()
      # runner.run(suite)
  case_demo03
  添加测试套件有很多种方法,见下:(测试套件可以给测试用例传参,方法见test_skip1)
  import unittest
  from case_demo03 import CaseDemo
  from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
  #构造测试集
  suite = unittest.TestSuite()
  # 套件添加测试用例 +++++++++++++++++++++++++++++++++++++++++++++++++++
  # # 第一种方法:逐个添加
  # # suite.addTest(CaseDemo('test_03')) # 这个test_03用了ddt传参,不会运行。。。不知为何
  # suite.addTest(CaseDemo('test_skip1',wechat=666)) # 可以重写CaseDemo的init方法,就可以传参数过去
  # suite.addTest(CaseDemo('test_assert'))
  # 第二种方法:列表添加多个
  cases = [CaseDemo('test_skip1',wechat='我是额外的参数'),
           CaseDemo('test_01'),
           CaseDemo('test_assert'),
           ]
  suite.addTests(cases)
  #
  # # 第三种方法:批量添加测试用例类
  # # 会执行路径下所有名字符合'case_demo*.py'的所有文件下测试用例类的所有测试用例
  # execute_path = './'
  # suite = unittest.defaultTestLoader.discover(start_dir=execute_path, pattern='case_demo*.py', top_level_dir=None)
  # # 第四种方法:基于类对象添加测试用例类
  # # 会执行类下面所有的测试用例
  # suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CaseDemo))
  # # 第五种方法:基于类名称添加测试用例类
  # # 会执行类下面所有的测试用例
  # suite.addTests(unittest.TestLoader().loadTestsFromName('case_demo03.CaseDemo'))
  # # 还有其他方法,用unittest.TestLoader()可以点出来
  # unittest.TestLoader().loadTestsFromModule()
  # unittest.TestLoader().loadTestsFromNames()
  if __name__=='__main__':
      # 执行测试套件
      runner = unittest.TextTestRunner()
      runner.run(suite)
  六、python使用BeautifulReport形成测试报告
  对于测试用例的执行结果,我们可以使用beautifulreport来生成美观的html测试报告,经过使用,总结以下特点:
  1.执行失败的错误信息可以直接显示在详情里面。
  2.执行成功的结果可以通过print来输出,就可以显示在测试报告详情里。
  3.测试用例的注释信息可以显示在报告中描述一栏。
  用法很简单,见下:
  import unittest
  from case_demo03 import CaseDemo
  from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
  #构造测试集
  suite = unittest.TestSuite()
  # 套件添加测试用例 +++++++++++++++++++++++++++++++++++++++++++++++++++
  # # 第一种方法:逐个添加
  # # suite.addTest(CaseDemo('test_03')) # 这个test_03用了ddt传参,不会运行。。。不知为何
  # suite.addTest(CaseDemo('test_skip1',wechat=666)) # 可以重写CaseDemo的init方法,就可以传参数过去
  # suite.addTest(CaseDemo('test_assert'))
  # 第二种方法:列表添加多个
  cases = [CaseDemo('test_skip1',wechat='我是额外的参数'),
           CaseDemo('test_01'),
           CaseDemo('test_assert'),
           ]
  suite.addTests(cases)
  #
  # # 第三种方法:批量添加测试用例类
  # # 会执行路径下所有名字符合'case_demo*.py'的所有文件下测试用例类的所有测试用例
  # execute_path = './'
  # suite = unittest.defaultTestLoader.discover(start_dir=execute_path, pattern='case_demo*.py', top_level_dir=None)
  # # 第四种方法:基于类对象添加测试用例类
  # # 会执行类下面所有的测试用例
  # suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CaseDemo))
  # # 第五种方法:基于类名称添加测试用例类
  # # 会执行类下面所有的测试用例
  # suite.addTests(unittest.TestLoader().loadTestsFromName('case_demo03.CaseDemo'))
  # # 还有其他方法,用unittest.TestLoader()可以点出来
  # unittest.TestLoader().loadTestsFromModule()
  # unittest.TestLoader().loadTestsFromNames()
  if __name__=='__main__':
      # # 执行测试套件
      # runner = unittest.TextTestRunner()
      # runner.run(suite)
      # 使用BeautifulReport执行套件并生成测试报告
      from BeautifulReport import BeautifulReport
      result = BeautifulReport(suite)
      # filename:测试报告报告名字
      # description:测试用例名字,会显示在图文进面
      # report_dir:报告存储路径,没有会自动创建
      # theme:默认即可,可不写
      result.report(filename='wxbot原子操作测试报告', description='测试deafult报告', report_dir='report', theme='theme_default')
  生成的报告如下图:
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号