目录

1、 UnitTest

1.1 TestCase

1.2 TestSuite

1.3 TextTestRunner

1.4 TestLoader

2、Fixture

2.1 方法级别

2.2 类级别

2.3 模块级别

2.4 总结

3、断言

3.1 UnitTest 常用断言方法

3.2 使用方式

4、参数化

4.1 安装 类库

4.2 使用

5、跳过

6、生成HTML测试报告


UnitTest 是 Python 自带的一个单元测试框架,用它来做单元测试。

为什么使用UnitTest框架?

  • 能够组织多个用例去执行;

  • 提供丰富的断言方法;

  • 能够生成测试报告;

1、 UnitTest

UnitTest 核心要素

  1. TestCase;

  2. TestSuite;

  3. TestRunner;

  4. TestLoader;

  5. Fixture;

1.1 TestCase

TestCase 就是测试用例的意思。

示例:

我们可以定义一个实现加法操作的函数,并对该函数进行测试。

# 导包
import unittest# 定义函数(方法)
def my_sum(i, j):return i + j;# 定义测试类 注:必须继承unittest.TestCase
class my_test(unittest.TestCase):# 定义测试方法 注: 测试方法名称命名以 test 开头;def test_01(self):print(my_sum(1, 2))def test_02(self):print(my_sum(3, 4))

1.2 TestSuite

TestSuite 翻译过来的意识就是 测试套件,多条测试用例集合在一起,就是一个 TestSuite。

使用:

1、实例化(suite:为 TestSuite 实例化的名称,你可以叫a,b,c 都可以)

suite = unittest.TestSuite()

2、添加用例(ClassName:为类名;MethodName:为方法名)

suite.addTest(ClassName("MethodName"))

3、添加扩展:(搜索指定 ClassName 内 test 开头的方法并添加到测试套件中)

suite.addTest(unittest.makeSuite(ClassName))

注:

TestSuite 需要配合 TextTestRunner 才能被执行

1.3 TextTestRunner

TextTestRunner 是用来执行测试用例和测试套件的

使用:

1、实例化: runner = unittest.TextTestRunner()

2、执行: runner.run(suite) # suite:为测试套件名称

示例:

这里我们多写将测试类分模块。

Test01.py

# 导包
import unittest# 定义函数(方法)
def my_sum(i, j):return i + j;# 定义测试类 my_test 注:必须继承unittest.TestCase
class my_test(unittest.TestCase):# 定义测试方法 注: 测试方法名称命名以 test 开头;def test_01(self):print("结果:%s" % my_sum(1, 2)+" my_test的test_01")def test_02(self):print("结果:%s" % my_sum(3, 4)+" my_test的test_02")

Test02.py

# 导包
import unittest# 定义函数(方法)
def my_sum(i, j):return i + j;class my_test02(unittest.TestCase):def test_01(self):print("结果:%s" % my_sum(1, 2)+" my_test02的test_01")def test_02(self):print("结果:%s" % my_sum(1, 2)+" my_test02的test_02")

Test.py :执行测试用例

import unittest
import Test01
import Test02# 实例化TestSuite
suite = unittest.TestSuite()
# 添加用例
suite.addTest(Test01.my_test("test_01"))
# 添加 my_test02 类中所有 test 开头的方法
suite.addTest(unittest.makeSuite(Test02.my_test02))
# 实例化TextTestRunner
runner = unittest.TextTestRunner()
# 执行
runner.run(suite)

1.4 TestLoader

用来加载 TestCase 到 TestSuite 中,即加载满足条件的测试用例,并把测试用例封装成测试套件。

使用 unittest.TestLoader,通过该类下面的 discover()方法自动搜索指定目录下指定开头的.py 文件,并将查找到的测试用例组装到测试套件;

使用:

suite = unittest.TestLoader().discover(test_dir, pattern='test*.py')

test_dir: 为指定的测试用例的目录;

pattern:为查找的.py 文件的格式;

注:

如果文件名默认为'test*.py' 也可以使用 unittest.defaultTestLoader 代替 unittest.TestLoader()

示例:

import unittest# 实例化 TestLoader
suite = unittest.TestLoader().discover("./", "test0*.py")
# 实例化TextTestRunner
runner = unittest.TextTestRunner()
# 执行
runner.run(suite)

TestSuite TestLoader 区别

  • TestSuite 需要手动添加测试用例(可以添加测试类,也可以添加测试类中某个测试方法);

  • TestLoader 搜索指定目录下指定开头.py 文件,并添加测试类中的所有的测试方法,不能指定添加测试方法;

2、Fixture

Fixture 是一个概述,对一个测试用例环境的初始化和销毁就是一个Fixture 。

Fixture有三个控制级别:

2.1 方法级别

在TestCase,也就是测试用例所在的class中定义方法,如果一个TestCase中有多个测试用例,那么setUp和tearDown就会被自动调用多次。

使用:

  • 初始化(前置处理): def setUp(self) --> 首先自动执行;

  • 销毁(后置处理): def tearDown(self) --> 最后自动执行;

运行于测试方法的始末,即:运行一次测试方法就会运行一次 setUp 和tearDown

示例:

# 导包
import unittest# 定义函数(方法)
def my_sum(i, j):return i + j;# 定义测试类 my_test 注:必须继承unittest.TestCase
class my_test(unittest.TestCase):# 初始化方法def setUp(self):print("setUP 执行初始化")# 销毁方法def tearDown(self):print("tearDown 执行销毁")# 定义测试方法 注: 测试方法名称命名以 test 开头;def test_01(self):print("结果:%s" % my_sum(1, 2) + " my_test的test_01")def test_02(self):print("结果:%s" % my_sum(3, 4) + " my_test的test_02")

2.2 类级别

不管类中有多少方法,一个类开始的时候自动调用函数,结束的之后自动调用函数。

使用:

  • 初始化(前置处理): @classmethod def setUpClass(cls): --> 首先自动执行

    • 销毁(后置处理): @classmethod def tearDownClass(cls): --> 最后自动执行

运行于测试类的始末 , 即: 每个测试类只会运行 一次 setUpClass 和 tearDownClass.

# 导包
import unittest# 定义函数(方法)
def my_sum(i, j):return i + j;# 定义测试类 my_test 注:必须继承unittest.TestCase
class my_test(unittest.TestCase):# 初始化@classmethoddef setUpClass(cls):print("setUP 执行初始化")# 销毁方法@classmethoddef tearDownClass(cls):print("tearDown 执行销毁")# 定义测试方法 注: 测试方法名称命名以 test 开头;def test_01(self):print("结果:%s" % my_sum(1, 2) + " my_test的test_01")def test_02(self):print("结果:%s" % my_sum(3, 4) + " my_test的test_02")

2.3 模块级别

不管py文件中有多少个类,以及类中有多少方法,只自动执行一次

使用:

  • 初始化(前置处理): def setUpModule(): --> 首先自动执行

  • 销毁(后置处理): def tearDownModule(): --> 最后自动执行

# 导包
import unittest# 定义函数(方法)
def my_sum(i, j):return i + j;# 模块级
def setUpModule():print("setUpModule自动调用了")# 模块级
def tearDownModule():print("tearDownModule自动调用了")# 定义测试类 my_test 注:必须继承unittest.TestCase
class my_test(unittest.TestCase):# 定义测试方法 注: 测试方法名称命名以 test 开头;def test_01(self):print("结果:%s" % my_sum(1, 2) + " my_test的test_01")def test_02(self):print("结果:%s" % my_sum(3, 4) + " my_test的test_02")# 定义测试类 my_test02
class my_test02(unittest.TestCase):def test_01(self):print("结果:%s" % my_sum(1, 2) + " my_test02的test_01")def test_02(self):print("结果:%s" % my_sum(1, 2) + " my_test02的test_02")

2.4 总结

  • 必须继承 unittest.TestCase 类,setUp、tearDown 才是一个 Fixture;

  • 方法级:setUp,tearDown:如果一个类中有多个测试用例,每执行一个测试用例之前会调用一次 setUp,之后会调用一次 tearDown;

  • 类级:setUpClass,tearDownClass:如果一个类中有多个测试用例,执行所有测试用例之前只会调用一次 setUpClass,之后只会调用一次 tearDownClass;

  • 模块级:setUpModule,tearDownModule:只在 import 导入这个模块时会调用一次 setUpModule,模块使用完成之后会调用一次 tearDownModule;

  • setUpXXX:一般做初始化工作; tearDownXXX:一般做结束工作;

3、断言

让程序代替人为判断测试程序执行结果是否符合预期结果的过程。

为什么要学习断言呢?

因为自动化脚本在执行的时候一般都是无人值守状态,我们不知道执行结果是否符合预期结果,所以我们需要让程序代替人为检测程序执行的结果是否符合预期结果,这就需要使用断言。

3.1 UnitTest 常用断言方法

UnitTest 中提供了非常丰富的断言方法,复杂的断言方法在自动化测试中几乎使用不到,所以我们只需要掌握几个常用的即可。

常用的 UnitTest 断言方法:

序号 断言方法 断言描述
1 assertTrue(expr, msg=None) 验证 expr 是 true,如果为 false,则 fail
2 assertFalse(expr, msg=None) 验证 expr 是 false,如果为 true,则 fail
3 assertEqual(expected, actual, msg=None) 验证 expected==actual,不等则 fail
4 assertNotEqual(first, second, msg=None) 验证 first != second, 相等则 fail
5 assertIsNone(obj, msg=None) 验证 obj 是 None,不是则 fail
6 assertIsNotNone(obj, msg=None) 验证 obj 不是 None,是则 fail
7 assertIn(member, container, msg=None) 验证是否 member in container
8 assertNotIn(member, container, msg=None) 验证是否 member not in container

3.2 使用方式

断言方法已经在 unittest.TestCase 类中定义好了,而且我们自定义的测试类已经继承了 TestCase,所以在测试方法中直接调用即可。

# 导包
import unittest# 定义函数(方法)
def my_sum(i, j):return i + j;# 定义测试类 my_test 注:必须继承unittest.TestCase
class my_test(unittest.TestCase):# 定义测试方法 注: 测试方法名称命名以 test 开头;def test_01(self):num = my_sum(1, 2)# 如果 num为4,正确self.assertEqual(3, num);def test_02(self):num = my_sum(3, 4)# 如果 num为7,正确self.assertEqual(7, num);def test_03(self):num = my_sum(1, 2)# 如果 num在列表中,正确self.assertIn(num,[1,2,3,4,5])

4、参数化

上面的测试用例都存在一个问题,都是一条测试数据定义一个测试函数,代码冗余度太高。

我们可以通过参数化的方式来传递数据,从而实现数据和脚本分离。

并且可以实现用例的重复执行。unittest测试框架,本身不支持参数化,但是可以通过安装 unittest扩展插件 parameterized 来实现。

4.1 安装 类库

方式一:

我们可以直接打开命令提示符输入:pip install parameterized

方式二 :

使用PyCharm 安装,直接看图

4.2 使用

方式一:

import unittest
from parameterized import parameterizeddef my_sum(i, j):return i + jclass my_test(unittest.TestCase):# a是调用my_sum的第一个参数# b是调用my_sum的第二个参数# c是预期结果@parameterized.expand([(1, 2, 3), (5, 6, 110), (-1, 3, 2)])def test_001(self, i, j, k):# 定义变量num得到my_sum函数的返回值num = my_sum(i, j)# num1里存放的是实际结果,k是预期结果self.assertEqual(num, k)# 实际结果与预期结果相符,代表测试用例测试通过# 不相符代表测试用例测试失败

方式二:

就是直接定义好一个列表,列表里面有元组。

方式三:

就是定义一个函数(方法),然后直接返回元组。

5、跳过

对于一些未完成的或者不满足测试条件的测试函数和测试类,可以跳过执行。

使用方式:

@unittest.skip('代码未完成'):直接将测试函数标记成跳过

@unittest.skipIf(condition, reason):根据条件判断测试函数是否跳过

示例:

6、生成HTML测试报告

HTML 测试报告就是执行完测试用例后,以 HTML(网页)方式将执行结果生成报告。

为什么要生产测试报告?

因为测试报告是本次测试结果的体现形态,然后测试报告内包含了有关本次测试用例的详情;

HTML 生成报告方式

一种是TextTestRunner (UnitTest 自带),另外的就是其他的第三方模板HTMLTestRunner。

首先我们先来看看TextTestRunner如何生成测试报告的。

import unittest# 生成测试套件
suite = unittest.TestLoader().discover("./", "test0*.py")
# 以只写方式打开测试报告文件
f = open("C:/Users/jie/Desktop/test.txt", "w", encoding="utf-8")
# 实例化TextTestRunner stream为open函数打开的文件流; verbosity 为不同模板编号
runner = unittest.TextTestRunner(stream=f,verbosity=2)
# 执行
runner.run(suite)
# 关闭
f.close()

结果

我们再来看看HTMLTestRunner 测试报告

首先要安装HTMLTestRunner,这里要注意的是由于HTMLTestRunner是一个第三方的unittest HTML报告库,用pip是死活安装不了的,得去网上下载HTMLTestRunner.py放到存放python源代码的Lib目录下。大家也可以用我下好的。

HTMLTestRunner: 这是python HTMLTestRunner

import unittest
from HTMLTestRunner import HTMLTestRunner# 生成测试套件
suite = unittest.TestLoader().discover("./", "test*.py")
# 以只写方式打开测试报告文件
f = open("C:/Users/jie/Desktop/test01.html", "wb")
# 实例化 HTMLTestRunner 对象  stream:open 函数打开的文件流; title:[可选参数],为报告标题; description:[可选参数],为报告描述信息;比如操作系统、浏览器等版本;
runner = HTMLTestRunner(stream=f, title="自动化测试报告", description="Chrome 浏览器")
# 执行
runner.run(suite)
# 关闭
f.close()

效果

Python学习之UnitTest【使用,生成HTML测试报告】相关推荐

  1. python学习之路—自动生成唯一标识(md5加密方式)

    前言 在python存入数据库时,如果数据库的主键不是自增方式,那么我们可能需要自己生成一个唯一标识符,现在最好的方法就是md5加密生成的32位作为主键,本文将会介绍python的两种自动生成唯一标识 ...

  2. python学习——二维码生成和识别

    二维码知识 在介绍二维码原理之前,先说下条形码 .条形码我们都见过,就是超市收银员结账的时候扫的那个东西.它是一种"一维码",竖直方向,条码是均匀的,信息只能在水平方向上存储,并且 ...

  3. 【Python学习】 - sklearn - 用于生成数据的make_blobs模块

    函数原型: sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=3, cluster_std=1.0, center_bo ...

  4. python学习中包的生成和调用(idle和pycharm)

    1.包其实就是文件夹 2.调用是用一个python文件调用其它的python文件 3.调用可以是不同包中调用 4.要调用一个包,必须在包的目录下有__init__.py文件 5.其他包调用也需要__i ...

  5. python学习记录之随机生成姓名

    def random_name():firstName = '赵钱孙李周吴郑王戚谢邹喻顾孟平黄熊纪舒屈江童颜郭郁单杭洪裴陆荣翁姬申扶堵漆雕乐正汝鄢涂钦羊舌微生伍余元卜'lastName = '伟刚勇毅 ...

  6. python学习 —— 使用QRCode包生成二维码

    我使用的是python3,最简单的方法就是使用QRCode,如果没有安装QRCode package,那么可以使用下面命令进行安装: pip3 install QRCode 然后,测试一下: from ...

  7. pyhton使用pytest框架生成allure测试报告

    一.基础环境 window环境:windows10python环境:python3.7pycharm: pycharm2020java环境:jdk1.8.0_151/jre1.8.0_301(可以不是 ...

  8. python appium自动化测试框架unittest_Appium基于Python unittest自动化测试 自动化测试框架 -- PO并生成html测试报告...

    基于python单元测试框架unittest完成appium自动化测试,生成基于html可视化测试报告 代码示例: #利用unittest并生成测试报告 class Appium_test(unitt ...

  9. Python用HTMLTestRunner生成html测试报告

    一.引入HTMLTestRunner包 1.下载HTMLTestRunner.py,已上传到网盘,点击下载 2.将HTMLTestRunner.py复制到python安装目录的Lib文件夹下. 可能有 ...

  10. Selenium+python怎么搭建自动化测试框架、执行自动化测试用例、生成自动化测试报告、发送测试报告邮件

    目录 一.项目结构介绍 1.mztestpro测试项目 2.bbs目录 3.test_case 二.编写公共模块 三.编写Page Object 四.编写测试用例 五.执行测试用例 小结: 本人在网上 ...

最新文章

  1. 【蓝桥java】进制与整除之天平秤重
  2. python爬虫正则表达式实例-Python爬虫(十一)_案例:使用正则表达式的爬虫
  3. 20145305 《信息安全系统设计基础》第6周学习总结
  4. 判断list集合不为空
  5. mysql触发器 node_node.js中事件触发器events的使用
  6. 接口测试(apipost、jmeter和python脚本)
  7. 【python学习-2】python起步必备
  8. 生意宝,淘宝,唯品会,58同城,去哪儿背后的赚钱生意经(转)
  9. linux 获取文件名的后缀名,linux shell 取文件名后缀
  10. 为什么html中使用不了样式,css不起作用是什么原因?
  11. Python爬虫——爬去必应壁纸(简化版)
  12. 【Matlab学习手记】Matlab积分问题
  13. php-opencv身份证识别,python opencv实现证件照换底功能
  14. 拉里·埃里森亲自支招,数据库自动化之后,DBA何去何从???
  15. Ubuntu 下旋转显示器屏幕
  16. 链游是什么意思 链游和游戏的区别是什么
  17. 通信软件设计基础(第2版)pdf分享
  18. 如何两个电脑共享文件实现多人编辑_怎么才能几台电脑同时编辑共享的同一word文档...
  19. 三相永磁同步电机Foc有感的程序控制(总结:程序2)
  20. 使用python进行复杂代数式的化简

热门文章

  1. 对“陶哲轩-来自特征值的特征向量”的理解
  2. 谷歌邮箱lmap服务器填什么_解决Gmail的imap收发邮件无法连接服务器的问题
  3. 【AIOT】HumanCenteredSensing
  4. 2月12日 模拟题 递推 题解
  5. Idea部署dubbo-admin
  6. 什么是数据增强(Data Augmentation)
  7. 运算符和强制类型转换
  8. 方正快速开发平台ES2007(3.5版本)新增功能特点
  9. thermal 代码分析
  10. docker-bridge如何通信