unittest的四大特点

  1. TestCase:测试用例。所有的用例都是直接继承与UnitTest.TestCase类。

  2. TestFixture:测试固件。setUp和tearDown分别作为前置条件和后置条件。主要用于初始化测试用例和管理用例执行结束后的资源释放。

  3. TestSuite和TestRunner:测试套件和测试运行器。

  4. 断言:在unittest中封装好了成熟的断言,可以直接调用。

unittest基本用法

  • 语法规则

    • unittest中,测试用例的名称,必须以“test_”开头。否则即便定义了测试用例也不会被执行。

    • 用例的执行顺序与定义的先后顺序无关,而是根据用例名称来排序执行的。如test_1会比test_2先执行。

  • 所有测试用例的运行

    • 在main代码块内调用unittest.main()

    

 1 import unittest
2
3
4 class TestDemo(unittest.TestCase):
5
6 def setUp(self) -> None:
7 print('执行每个测试用例前的准备工作')
8
9 def tearDown(self) -> None:
10 print('执行完每个测试用例后的收尾工作')
11
12 def test_1(self):
13 print('测试用例1')
14
15 def test_2(self):
16 print('测试用例2')
17
18 def a(self):
19 print('不按命名规则的测试用例')
20
21
22 if __name__ == '__main__':
23 unittest.main()
24
25
26
27 执行结果:
28
29 执行每个测试用例前的准备工作
30 测试用例1
31 执行完每个测试用例后的收尾工作
32 执行每个测试用例前的准备工作
33 测试用例2
34 执行完每个测试用例后的收尾工作
35 ..
36 ----------------------------------------------------------------------
37 Ran 2 tests in 0.000s
38
39 OK

数据驱动测试

  • ddt模块的使用

    • ddt模块的data装饰器可以给测试用例传入数据

    • 需要使用ddt模块给测试用例传入数据,需要先使用ddt装饰器给对应的测试用例的类进行装饰

 1 import unittest
2 from ddt import ddt, data
3
4
5 @ddt
6 class TestDemo(unittest.TestCase):
7
8 def setUp(self) -> None:
9 print('执行每个测试用例前的准备工作')
10
11 def tearDown(self) -> None:
12 print('执行完每个测试用例后的收尾工作')
13
14 @data('我是传入的数据')
15 def test_1(self, data):
16 print(data)
17
18
19 if __name__ == '__main__':
20 unittest.main()
  • 注意点

    • 如果data装饰器传入多条数据,表示该用例会被执行多少次,每次使用不同的数据来测试

     1 import unittest
    2 from ddt import ddt, data
    3
    4
    5 @ddt
    6 class TestDemo(unittest.TestCase):
    7
    8 def setUp(self) -> None:
    9 print('执行每个测试用例前的准备工作')
    10
    11 def tearDown(self) -> None:
    12 print('执行完每个测试用例后的收尾工作')
    13
    14 @data('我是传入的数据1', '我是传入的数据2')
    15 def test_1(self, data1):
    16 print(data1)
    17
    18
    19 if __name__ == '__main__':
    20 unittest.main()
    21
    22 执行结果:
    23 执行每个测试用例前的准备工作
    24 我是传入的数据1
    25 执行完每个测试用例后的收尾工作
    26 执行每个测试用例前的准备工作
    27 我是传入的数据2
    28 执行完每个测试用例后的收尾工作
    29 ..
    30 ----------------------------------------------------------------------
    31 Ran 2 tests in 0.000s
    32
    33 OK
    • 如果测试用例的函数需要接收多个参数,需要将每一组数据放在列表中传入

      • 需要特别注意的是,即便使用列表将多个参数对应的数据传入测试用例。整个列表还是会被当做是一个整体默认传给第一个参数,此时使用*[]语法是错误的,这样列表中的元素会被拆分成一个个独立的元素,作为每一次测试使用的测试数据。

      • 此时需要使用ddt模块中的例外一个装饰器—unpack。它会负责将列表内的元素对应的传给参数。

     1 import unittest
    2 from ddt import ddt, data, unpack
    3
    4
    5 @ddt
    6 class TestDemo(unittest.TestCase):
    7
    8 def setUp(self) -> None:
    9 print('执行每个测试用例前的准备工作')
    10
    11 def tearDown(self) -> None:
    12 print('执行完每个测试用例后的收尾工作')
    13
    14 @data(['我是传入的数据1', '我是传入的数据2'], ['第二组用例的数据1', '第二组用例的数据2'])
    15 @unpack
    16 def test_1(self, data1, data2):
    17 print(data1)
    18 print(data2)
    19
    20
    21 if __name__ == '__main__':
    22 unittest.main()
    23
    24
    25 执行结果:
    26 执行每个测试用例前的准备工作
    27 我是传入的数据1
    28 我是传入的数据2
    29 执行完每个测试用例后的收尾工作
    30 执行每个测试用例前的准备工作
    31 第二组用例的数据1
    32 第二组用例的数据2
    33 执行完每个测试用例后的收尾工作
    34 ..
    35 ----------------------------------------------------------------------
    36 Ran 2 tests in 0.000s
    37
    38 OK

断言

  • 断言就是一个测试用例预期结果与实际结果的对比(实际结果是否与预期符合)

  • unittest的常用的一些断言:

    # 判断 a == b,msg表示错误提示信息
    self.assertEqual(a, b, msg='a不等于b') # 判断 a != b
    self.assertNotEqual(a, b) # 判断 bool(x) is True
    self.assertTrue(x) # 判断 bool(x) is False
    self.assertFalse(x) # 判断 a is b
    self.assertIs(a, b) # 判断 a is not b
    self.assertIsNot(a, b) # 判断 x is None
    self.assertIsNone(x) # 判断 x is not None
    self.assertIsNotNone(x) # 判断 a in b
    self.assertIn(a, b) # 判断 a not in b
    self.assertNotIn(a, b) # 判断 isinstance(a, b)
    self.assertIsInstance(a, b) # 判断 not isinstance(a, b)
    self.assertNotIsInstance(a, b)
     

Skip操作

  • 将某些暂时不需要执行的测试用例跳过

    1 @unittest.skip('无条件跳过')
    2 def test_1(self, data1, data2):
    3 print(data1)
    4 print(data2)
    5 self.assertEqual(1, 2, msg='1不等于2')
  • 给指定测试用例加上skip装饰器,即可无条件跳过该测试用例

  • 有条件限制的跳过测试用例:

    • skipUnless装饰器

      • 当条件为False时会跳过当前测试用例

      1 @unittest.skipUnless(1 > 2, '条件为假跳过')
      2 def test_2(self):
      3 print(111)
    • skipIf装饰器

      • 当条件为True时会跳过当前测试用例

      1 @unittest.skipIf(2 > 1, '条件为真时跳过')
      2 def test_3(self):
      3 print(222)
  • 测试用例断言为假时(与预期结果不符)标记该测试用例

    • expectedFailure装饰器

      1 @unittest.expectedFailure
      2 def test_4(self):
      3 self.assertEqual(1, 2, '1不等于2')
      4
      5 该测试用例被标记为:
      6 expected failures=1
      7 注意:
      8 和skip不同,skip是根据条件或者无条件跳过不执行测试用例
      9 expectedFailure是执行完测试用例后,将与预期不符的测试用例标记出来

    使用了该装饰器的测试用例,断言结果必须是错误的。不允许成功

    否则会出现以下错误:

    Test should not succeed since it's marked with @unittest.expectedFailure

测试套件和测试运行器

  • 测试套件

    • 将想要执行的测试用例加入到一个测试套件内,然后通过运行器执行测试套件内的测试用例,即可实现执行部分测试用例。

    • 测试套件不能与测试用例在一个文件内,否则即使使用测试运行器运行测试套件,还是会执行所有用例。

       1 import unittest
      2 from test import TestDemo
      3
      4 # 实例化测试套件
      5 suite = unittest.TestSuite()
      6 # 添加测试用例
      7 suite.addTest(TestDemo('test_1'))
      8 suite.addTest(TestDemo('test_3'))
      9
      10 # 实例化测试运行器
      11 runner = unittest.TextTestRunner()
      12 runner.run(suite)
  • 往测试套件内添加测试用例的多种方式:

    • 上述例子中,直接通过指定测试用例类中的测试用例方法名,将测试用例添加至套件内。

      • 上述例子添加用例的方式可优化:

        1 cases = [TestDemo('test_1'), TestDemo('test_3')]
        2 suite.addTests(cases)
    • 通过正则匹配查询,将指定路径下所有匹配成功的测试用例全都加入测试套件内

      1 discover = unittest.defaultTestLoader.discover(start_dir='./', pattern='test*.py')
      2 ​
      3 # 实例化测试运行器
      4 runner = unittest.TextTestRunner()
      5 runner.run(discover)
      6 ​
      7 # 此时运行器执行的是从‘./’路径下,也就是当前路径下所有与‘test*.py’相匹配的测试用例文件内的测试用例的集合。
    • 直接将指定测试用例类对象中的所有测试用例添加至套件内

      1 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestDemo))
    • 将上述方式改为通过类名称方式将所有用例添加至套件内

      1 suite.addTests(unittest.TestLoader().loadTestsFromName('test.TestDemo'))
      2 ​
      3 # 注意类名称必须通过指定包/模块加‘.’的形式
  • 测试运行器

    • 主要用于执行测试套件

HTMLTestRunner

  • 用于生成测试报告

    • 报告内只记录通过的用例和失败的用例,没有跳过的用例。

  • HTMLTestRunner配置

    • 下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

    • 由于下载的HTMLTestRunner.py文件是基于Python2的,若适用于Python3则进行如下修改:

      • 94行, import StringIO

      • 539行,self.outputBuffer = StringIO.StringIO()

      • 631行,print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)

      • 642行,if not rmap.has_key(cls):

      • 766行,uo = o.decode('latin-1')

      • 772行,ue = e.decode('latin-1')

    • 将下载的文件保存到:PythonXX\Lib目录下。

  • 基本用法     

 1 import unittest
2 from HTMLTestRunner import HTMLTestRunner
3 from test import TestDemo
4 ​
5 # 实例化测试套件
6 suite = unittest.TestSuite()
7 ​
8 # 生成测试报告
9 report_name = '测试报告名称.html'
10 report_title = '测试报告标题'
11 report_desc = '测试报告描述'
12 report_path = './'
13 report_file = report_path + report_name
14 ​
15 with open(report_file, 'wb') as report:
16 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestDemo))
17 runner = HTMLTestRunner(stream=report, title=report_title, description=report_desc)
18 runner.run(suite)

unittest学习的更多相关文章

  1. Python unittest 学习

    import unittest class UTest(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper() ...

  2. unittest学习5-断言

    unittest提供了以下断言方式: 方法 检查 新进 assertEqual(a, b) a == b   assertNotEqual(a, b) a != b   assertTrue(x) b ...

  3. unittest学习4-跳过用例执行

    unittest支持跳过单个测试方法,甚至整个测试用例,还支持将测试用例标记为“测试失败” 基本跳过如下: import unittestimport requests,sys class MyTes ...

  4. unittest学习3-测试组件setup、teardown

    unittest的测试用例执行时都可以设置setup.teardown,用来初始化测试开始和测试结束关闭,例如: import unittest class MyTestCase(unittest.T ...

  5. unittest学习笔记

    File "C:\Program Files\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py&quo ...

  6. ios UnitTest 学习笔记

    一.运行第一个单元测试: 1.在Xcode 5中新建一个工程默认自带一个单元测试的文件夹,IDE自动生成了一个实现XCTestCase的.m文件,里面有一个失败测试(早期版本中实现的是SenTestC ...

  7. ios UnitTest 学习笔记1

    一.运行第一个单元测试: 1.在Xcode 5中新建一个工程默认自带一个单元测试的文件夹,IDE自动生成了一个实现XCTestCase的.m文件,里面有一个失败测试(早期版本中实现的是SenTestC ...

  8. 12.unittest的学习

    unittest学习后的总结,记录各个主要内容

  9. appium学习记录2

    unittest 学习 每执行一次 testcase 就会调用一次 setUP 与teardown 类方法只会执行一次 开始 与结束时候执行 类似反射方法 __init__ 与 __del__ set ...

随机推荐

  1. js动画之轮播图

    一. 使用Css3动画实现 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  2. matlab外部程序接口-excel

    在excel中使用matlab 内容: 1.Spreadsheet Link 程序 安装与启动 1 打开excle->文件->选项 2.加载项->转到 3.浏览(可用加载宏,本来没有 ...

  3. springboot 配置和使用过滤器

    首先在Application文件中添加注解@ServletComponentScan自动扫描当前类的同包以及子包,这样才能将filter装入bean package com.example.acade ...

  4. java虚拟机之性能监控与故障处理工具

    sun jdk性能监控与故障处理工具 jps: 可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一id. jstat: 用于监视虚拟机各种运行状态信息的命令航工具.它可 ...

  5. J.U.C之ReentrantLock 可重入锁

    * A reentrant mutual exclusion {@link Lock} with the same basic * behavior and semantics as the impl ...

  6. 实战Docker容器调度

    目录 一.前言 二.Docker Compose 2.1.简介 2.2.下载安装 2.3.小实验 2.4.小实验的细节 2.5.Compose file的编写规则 三.Docker Swarm 3.1 ...

  7. 【JAVA】HashMap源码阅读

    目录 1.关键的几个static参数 2.内部类定义Node节点 3.成员变量 4.静态方法 5.HashMap的四个构造方法 6.put方法 7.扩容resize方法 8.get方法 9.remov ...

  8. 轻轻松松学CSS:overflow

    一.overflow的定义 overflow,音[əʊvəˈfləʊ],义[溢出],就像2.2米的人躺在1.8米的床上,腿得耷拉到床外一样.overflow 属性用于控制内容溢出容器时显示的方式 二. ...

  9. BurpSuite抓取本地包方法

    本文重点在介绍抓本地包, 而非介绍抓包步骤 Burpsuite配置 默认配置即可 Chrome 浏览器配置 Falcon Proxy扩展程序配置浏览器代理. 需要抓包的网页是个本地搭建的网址, 一般会 ...

  10. js自动生成条形码插件-JsBarcode

    JsBarcode.html <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...