Unittest框架,理论和实操双管齐下(上)

发表于:2023-9-25 09:06

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

 作者:程序员小濠    来源:知乎

  1、什么是Unittest框架?
  python自带一种单元测试框架
  2、为什么使用Unittest框架?
  >批量执行用例
  >提供丰富的断言知识
  >可以生成报告
  3、核心要素:
  1). TestCase(测试用例
  2). TestSuite(测试套件)
  3). TestRunner(测试执行,执行TestUite测试套件的)
  4). TestLoader(批量执行测试用例-搜索指定文件夹内指定字母开头的模块) 【推荐】
  5). Fixture(固定装置(两个固定的函数,一个初始化时使用,一个结束时使用))
  接下来会展开 核心要素来认识Unittest框架:
  首先介绍下unittest的用例规则:
  1、测试文件必须导包:import unittest
  2、测试类必须继承 unittest.TestCase
  3、测试方法必须以 test_开头
  一、TestCase(测试用例)
  1、是一个代码文件,在代码文件中来书写真正的用例代码 (里面的print均是模拟测试用例)
  # 1、导包
  # 2、自定义测试类
  # 3、在测试类中书写测试方法 采用print 简单书写测试方法
  # 4、执行用例
  import unittest
  # 2、自定义测试类,需要继承unittest模块中的TestCase类即可
  class TestDemo(unittest.TestCase):
      # 书写测试方法,测试用例代码,书写要求,测试方法必须test_ 开头
      def test_method1(self):
          print('测试方法1-1')
      def test_method2(self):
          print('测试方法1-2')
  # 4、执行测试用例
  # 4.1 光标放在类后面执行所有的测试用例
  # 4.2 光标放在方法后面执行当前的方法测试用例
  说明:def 定义的test_ 是测试用例,只有执行 if __name__ == '___mian___' 的时候会执行测试用例,其他普通函数则不执行,通过 self 来调用执行。
  二、TestSuite(测试套件)和TestRunner(测试执行)
  1、TestSuite(测试套件):用来组装,打包 ,管理多个TestCase(测试用例)文件的
  2、TestRunner(测试执行):用来执行 TestSuite(测试套件的)
  代码:首先要准备多个测试用例的文件才可以实现TestSuite和TestRunner,以下代码是已经准备了unittest_Demo2和unittest_Demo1两个测试用例文件
  # 1、导包
  # 2、实例化(创建对象)套件对象
  # 3、使用套件对象添加用例方法
  # 4、实例化对象运行
  # 5、使用运行对象去执行套件对象
  import unittest
  from unittest_Demo2 import TestDemo
  from unittest_Demo1 import Demo
  suite = unittest.TestSuite()
  # 将?个测试类中的所有?法进?添加
  # 套件对象.addTest(unittest.makeSuite(测试类名))
  suite.addTest(unittest.makeSuite(TestDemo))
  suite.addTest(unittest.makeSuite(Demo))
  # 4、实例化运行对象
  runner = unittest.TextTestRunner();
  # 5、使用运行对象去执行套件对象
  # 运?对象.run(套件对象)
  runner.run(suite)
  三、TestLoader(测试加载)
  说明:
  1. 将符合条件的测试方法添加到测试套件中
  2. 搜索指定目录文件下指定字母开头的模块文件下test开始的方法,并将这些方法添加到测试套件中,最后返回测试套件
  3. 与Testsuite功能一样,对他功能的补充,用来组装测试用例
  一般测试用例是写在Case这个文件夹里面,当测试用例超多的时候就可以考虑 TestLoader
  写法:
  1. suite = unittest.TestLoader().discover("指定搜索的目录文件","指定字母开头模块文件")
  2. suite = unittest.defaultTestLoader.discover("指定搜索的目录文件","指定字母开头模块文件") 【推荐】
  注意:
    如果使用写法1,TestLoader()必须有括号。
  # 1. 导包
  # 2. 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
  # 3. 实例化 运行对象
  # 4. 运行对象执行套件对象
  import unittest
  # 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
  # unittest.defaultTestLoader.discover('用例所在的路径', '用例的代码文件名')
  # 测试路径:相对路径
  # 测试文件名:可以使用 * 通配符,可以重复使用
  suite = unittest.defaultTestLoader.discover('./Case', 'cs*.py')
  runner = unittest.TextTestRunner()
  runner.run(suite)
  TestSuite与TestLoader区别:
    共同点:都是测试套件
    不同点:实现方式不同
      TestSuite: 要么添加指定的测试类中所有test开头的方法,要么添加指定测试类中指定某个test开头的方法
      TestLoader: 搜索指定目录下指定字母开头的模块文件中以test字母开头的方法并将这些方法添加到测试套件中,最后返回测试套件
  四、Fixture(测试夹具)
  是一种代码结构,在某些特定情况下,会自动执行。
  4.1 方法级别
  在每个测试方法(用例代码)执行前后都会自动调用的结构
  def setUp(),每个测试方法执行之前都会执行 (初始化)
  def tearDown(),每个测试方法执行之后都会执行 (释放)
  特性:几个测试函数,执行几次。每个测试函数执行之前都会执行 setUp,执行之后都会执行tearDwon
  # 初始化
  def setUp(self):
      # 每个测试方法执行之前执行的函数
      pass
  # 释放
  def tearDown(self):
      # 每个测试方法执行之后执行的函数
      pass
  场景:当你要登录自己的用户名账户的时候,都会输入网址,当你准备不用这个页面了,都会关闭当前页面;
    1、输入网址 (方法级别)
    2、关闭当前页面 (方法级别)
  4.2 类级别
  在每个测试类中所有方法执行前后 都会自动调用的结构(在整个类中 执行之前执行之后各一次)
  def setUpClass() ,类中所有方法之前
  def tearDownClass(),类中所有方法之后
  特性:测试类运行之前运行一次setUpClass ,类运行之后运行一次tearDownClass
  注意:类方法必须使用 @classmethod修饰
  @classmethod
      def setUpClass(cls):
          print('-----------1.打开浏览器')
      @classmethod
      def tearDownClass(cls):
          print('------------5、关闭浏览器')
  场景:你上网的整个过程都首先需要打开浏览器,关闭浏览器,而他们整个过程都需要执行一次,那么就可以用类级别。
  案列模板:结合了类级别和方法级别实现的.
  提示:
    无论使用函数级别还是类级别,最后常用场景为:
      初始化:
        1. 获取浏览器实例化对象
        2. 最大化浏览器
        3. 隐式等待
      结束:
        关闭浏览器驱动对象
  五、断言 ☆
  1、什么是断言:
  让程序代替人工自动的判断预期结果和实际结果是否相符
  断言的结果:
  1)、True,用例通过
  2)、False,代码抛出异常,用例不通过
  3)、在unittest中使用断言,需要通过 self.断言方法
  2、为什么要断言:
  自动化脚本执行时都是无人值守,需要通过断言来判断自动化脚本的执行是否通过
  注:自动化脚本不写断言,相当于没有执行测试一个效果。
  3、常用的断言:
  self.assertEqual(ex1, ex2) # 判断ex1 是否和ex2 相等
  self.assertIn(ex1, ex2) #  ex2是否包含 ex1   注意:所谓的包含不能跳字符
  self.assertTrue(ex) #  判断ex是否为True
  重点讲前两个assertEqual 和 assertIn
  方法:
  assertEqual:self.assertEqual(预期结果,实际结果) 判断的是预期是否相等实际
  assertIn:self.assertIn(预期结果,实际结果) 判断的是预期是否包含实际中
  assertIn('admin', 'admin') # 包含
  assertIn('admin', 'adminnnnnnnn') # 包含
  assertIn('admin', 'aaaaaadmin') # 包含
  assertIn('admin', 'aaaaaadminnnnnnn') # 包含
  assertIn('admin', 'addddddmin') # 不是包含
  # Login 函数我已经封装好了,这里直接导包调用就可以了。
  import unittest
  from login import Login
  class TestLogin(unittest.TestCase):
      """正确的用户名和密码: admin, 123456, 登录成功"""
      def test_success(self):
          self.assertEqual('登录成功', Login('admin', '123456'))
      def test_username_error(self):
          """错误的用户名: root, 123456, 登录失败"""
          self.assertEqual('登录失败', Login('root', '123456'))
      def test_password_error(self):
          """错误的密码: admin, 123123, 登录失败"""
          self.assertEqual('登录失败', Login('admin', '123123'))
      def test_error(self):
          """错误的用户名和错误的密码: aaa, 123123, 登录失败"""
          # self.assertEqual('登录失败',Login('登陆失败','123123'))
          self.assertIn('失败', Login('登录失败', '123123'))
  六、跳过
  对于一些未完成的或者不满足测试条件的测试函数和测试类, 不想执行,可以使用跳过
  """
  使用方法,装饰器完成
  代码书写在 TestCase 文件
  """
  # 直接将测试函数标记成跳过
  @unittest.skip('跳过条件')
  # 根据条件判断测试函数是否跳过 , 判断条件成立, 跳过
  @unittest.skipIf(判断条件,'跳过原因')
  import unittest
  version = 20
  class TestDemo1(unittest.TestCase):
      
      @unittest.skip('直接跳过')
      def test_method1(self):
          print('测试用例1-1')
      @unittest.skipIf(version > 19, '版本大于19,测试跳过')
      def test_method2(self):
          print('测试用例1-2')
  结果
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号