Python实战:UnitTest,Fixture,断言,参数化

UnitTest

一、UnitTest 基本使用

1. 什么是 UnitTest 框架?

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

2. 为什么使用 UnitTest 框架?

  • 能够组织多个用例去执行;
  • 提供丰富的断言方法;
  • 能够生成测试报告;

3. UnitTest 核心要素

  • TestCase
  • TestSuite
  • TestRunner
  • TestLoader
  • Fixture

4. TestCase

说明: TestCase 就是测试用例的意思。
案例:
定义一个实现加法操作的函数,并对该函数进行测试。
定义测试用例:
1 、导包: import unittest
2 、定义测试类:新建测试类必须继承 unittest.TestCase
3 、定义测试方法:测试方法名称命名必须以 test 开头;
4 、调用 unittest.main() 执行测试用例 ;
# a.py # 导包 
import unittest 
def my_sum(a, b): 
   return a + b 
class my_test(unittest.TestCase): 
    def test_01(self): 
       print(my_sum(4, 6)) 
    def test_02(self): 
       print(my_sum(3, 2))
思考:如何同时运行多个 py 文件中的测试用例?

二、TestSuite

说明: ( 翻译:测试套件 ) 多条测试用例集合在一起,就是一个 TestSuite
使用:
1 、实例化: suite = unittest.TestSuite()
(suite :为 TestSuite 实例化的名称 )
2 添加用例: suite.addTest(ClassName("MethodName"))
(ClassName :为类名; MethodName :为方法名 )
3 添加扩展: suite.addTest(unittest.makeSuite(ClassName))
( 搜索指定 ClassName test 开头的方法并添加到测试套件中 )
提示: TestSuite 需要配合 TextTestRunner 才能被执行

三、TextTestRunner

说明: TextTestRunner 是用来执行测试用例和测试套件的
使用:
1、实例化: runner = unittest.TextTestRunner()
2、执行: runner.run(suite) # suite:为测试套件名称

四、案例:

test01.py..test02.py 2 条用例,将这 2 条用例批量执行;
1. 示例代码
test01.py
# test01.py 
# 导包 
import unittest class my_test01(unittest.TestCase): 
    def test_01(self): 
       print("my_test01 的 test01") 
    def test_02(self): 
       print("my_test01 的 test02")
test02.py
# test02.py
# 导包
import unittest
class my_test02(unittest.TestCase):
   def test_01(self):
      print("my_test02 的 test01")
   def test_02(self):
      print("my_test02 的 test02")
import unittest 
import test01 
import test02 
suite = unittest.TestSuite() 
suite.addTest(test01.my_test01("test_01")) 
# 添加 my_test02 类中所有 test 开头的方法 
suite.addTest(unittest.makeSuite(test02.my_test02)) 
runner = unittest.TextTestRunner() 
runner.run(suite)
问题:使用 suite.addtest(unittest.makeSuite(className)) 导入多条测试用例,
addtest() 需要调用多次。

五、TestLoader

说明: 用来加载 TestCase TestSuite 中,即加载满足条件的测试用例,并把 测试用例封装成测试套件。
使用 unittest.TestLoader ,通过该类下面的 discover()方法自动搜索指定目录下 指定开头的 .py 文件,并将查找到的测试用例组装到测试套件;
用法: suite = unittest.TestLoader().discover(test_dir, pattern='test*.py')
自动搜索指定目录下指定开头的 .py 文件,并将查找到的测试用例组 装到测试套件;
test_dir: 为指定的测试用例的目录;
pattern :为查找的 .py 文件的格式;
如果文件名默认为 'test*.py' 也可以使用 unittest.defaultTestLoader 代替 unittest.TestLoader()
运行:
runner = unittest.TextTestRunner()
runner.run(suite)
 1. 示例代码
import unittest 
suite = unittest.TestLoader().discover("./", "test*.py") 
# suite = unittest.defaultTestLoader.discover("./")
runner = unittest.TextTestRunner() 
runner.run(suite)

六、TestSuite TestLoader 区别

  • TestSuite 需要手动添加测试用例(可以添加测试类,也可以添加测试类中某个测试方法);
  • TestLoader 搜索指定目录下指定开头.py 文件,并添加测试类中的所有的测试方法,不能指定添加测试方法;

Fixture

一、Fixture 介绍

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

二、Fixture 控制级别:

  • 方法级别;
  • 类级别;
  • 模块级别;

三、方法级别

使用:
初始化 ( 前置处理 ): def setUp(self) --> 首先自动执行;
销毁 ( 后置处理 ): def tearDown(self) --> 最后自动执行;
运行于测试方法的始末,即:运行一次测试方法就会运行一次 setUp
tearDown
1. 示例代码
test01.py
# test01.py 
import unittest 
class my_test01(unittest.TestCase):
   def setUp(self): 
      print("setUP 执行") 
   def tearDown(self): 
      print("teardown 执行")
   def test_01(self): 
      print("my_test01 的 test01") 
   def test_02(self):
      print("my_test01 的 test02")

四、类级别

使用:
初始化 ( 前置处理 ): @classmethod def setUpClass(cls): --> 首先自动执行
销毁 ( 后置处理 ): @classmethod def tearDownClass(cls): --> 最后自动执行
运 行于 测试 类的 始末 , 即: 每个 测试 类 只会 运行 一次 setUpClass 和 tearDownClass
1. 示例代码 test01.py 
# test01.py
# 导包 
import unittest 
class my_test01(unittest.TestCase): 
    @classmethod 
    def setUpClass(cls): 
       print("setUPClass 执行") 
    @classmethod 
    def tearDownClass(cls): 
       print("tearDownClass 执行") 
    def setUp(self): 
       print("setUP 执行") 
    def tearDown(self): 
       print("teardown 执行") 
    def test_01(self): 
       print("my_test01 的 test01") 
    def test_02(self): 
       print("my_test01 的 test02")

五、模块级别 [了解]

使用:
初始化 ( 前置处理 ): def setUpModule() --> 首先自动执行
销毁 ( 后置处理 ): def tearDownModule() --> 最后自动执行
运行于整个模块的始末,即:整个模块只会运行一次 setUpModule 和tearDownModule

六、总结

  • 必须继承 unittest.TestCase 类,setUptearDown 才是一个 Fixture
  • setUptearDown:如果一个类中有多个测试用例,每执行一个测试用例之前会调用一次 setUp,之后会调用一次 tearDown
  • setUpClasstearDownClass:如果一个类中有多个测试用例,执行所有测试用例之前只会调用一次 setUpClass,之后只会调用一次 tearDownClass
  • setUpModuletearDownModule:只在 import 导入这个模块时会调用一次
  • setUpModule,模块使用完成之后会调用一次 tearDownModule
  • setUpXXX:一般做初始化工作;
  • tearDownXXX:一般做结束工作;

 断言

一、目标

理解什么是断言;
掌握断言 assertEqual assertIn 方法;
了解 UnitTest 其他断言方法。

二、UnitTest 断言

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

三、为什么要学习断言?

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

四、UnitTest 常用断言方法

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

五、使用方式

断言方法已经在 unittest.TestCase 类中定义好了,而且我们自定义的测试类已经继承了 TestCase ,所以在测试方法中直接调用即可。
# a.py 
import unittest 
   def my_sum(a, b): 
      return a + b 
class my_test(unittest.TestCase): 
    def test01(self): 
       num = my_sum(1, 3) 
    # 如果 num 为 4,正确 
      self.assertEqual(4, num) 
    def test02(self): 
       num = my_sum(4, 3) 
    # 如果 num 为 4,正确 
       self.assertEqual(4, num) 
    def test03(self): 
       num = my_sum(1, 2) 
    # 如果 num 在列表中,正确 
       self.assertIn(num, [1, 2, 3, 4, 5])

参数化

一、目标

掌握如何实现参数化。

二、需求

定义一个实现加法操作的函数,并对该函数进行测试。
# a.py 
import unittest 
# 求和 
def my_sum(a, b): 
   return a + b 
class TestAdd(unittest.TestCase): 
    def test_01(self): 
       result = my_sum(1, 1) 
       self.assertEqual(result, 2) 
    def test_02(self): 
       result = my_sum(1, 0) 
       self.assertEqual(result, 1) 
    def test_03(self): 
       result = my_sum(0, 0) 
       self.assertEqual(result, 0)
发现问题
一条测试数据定义一个测试函数,代码冗余度太高;

三、参数化

通过参数化的方式来传递数据,从而实现数据和脚本分离。并且可以实现用
例的重复执行。 unittest 测试框架,本身不支持参数化,但是可以通过安装 unittest
扩展插件 parameterized 来实现。
安装
pip install parameterized
使用方式
导包: from parameterized import parameterized;
使用 @parameterized.expand 装饰器可以为测试函数的参数进行参数化 ;
方式一 :
# a.py 
import unittest from parameterized 
import parameterized 
# 求和 
def my_sum(a, b): 
   return a + b 
class Testmy_sum(unittest.TestCase): 
   @parameterized.expand([(1, 1, 2), (1, 0, 1), (0, 0, 0)]) 
def test_01(self, x, y, expect): 
   result = my_sum(x, y) self.assertEqual(result, expect)
# a.py 
import unittest from parameterized 
import parameterized 
# 求和 
def my_sum(a, b): 
   return a + b 
# 构建测试数据 
data = [(1, 1, 2), (1, 0, 1), (0, 0, 0)] 
class Testmy_sum(unittest.TestCase):
    @parameterized.expand(data) 
    def test_02(self, x, y, expect): 
       result = my_sum(x, y) 
       self.assertEqual(result, expect)
# a.py 
import unittest from parameterized 
import parameterized 
# 求和 
def my_sum(a, b): 
   return a + b 
# 构建测试数据 
def build_data(): 
   return [(1, 1, 2), (1, 0, 1), (0, 0, 0)] 
class Testmy_sum(unittest.TestCase): 
   @parameterized.expand(build_data) 
   def test_03(self, x, y, expect): 
      result = my_sum(x, y) 
      self.assertEqual(result, expect)

跳过

一、目标

掌握如何把测试函数标记成跳过。

二、跳过

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

三、使用方式

# 直接将测试函数标记成跳过
@unittest.skip('代码未完成')
# 根据条件判断测试函数是否跳过
@unittest.skipIf(condition, reason)
# a.py 
import unittest 
version = 35 
class My_Test1(unittest.TestCase): 
    @unittest.skip("代码未完成") 
    def test_01(self): 
       print("test_01") 
    @unittest.skipIf(version <= 30, "版本大于 30 才会执行")
    def test_02(self): 
       print("test_02")
    @unittest.skip("代码未完成") 
class My_Test2(unittest.TestCase): 
    def test_a(self): 
       print("test_a") 
    def test_b(self): print("test_b")

生成 HTML 测试报告

一、目标

掌握如何生成 HTML 测试报告方法。

二、什么是 HTML 测试报告

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

三、为什么要生成测试报告

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

四、HTML 生成报告方式

TextTestRunner (UnitTest 自带);
HTMLTestRunner (第三方模板);

五、生成 TextTestRunner 测试报告

1 、导入 unittest 包;
2 、生成测试套件 suite = unittest.TestLoader().discover("./", "test*.py")
3 、 以 只 写 方 式 打 开 测 试 报 告 文 件 f = open("test01.txt", "w", encoding="utf-8")
4 、实例化 HTMLTestRunner 对象: runner = unittest.TextTestRunner(stream=f,
verbosity=2)
参数说明: stream open 函数打开的文件流;
verbosity 为不同模板编号
5 、执行: runner.run(suite)
6 、关闭文件;
import unittest 
suite = unittest.TestLoader().discover("./", "test*.py") 
f = open("test01.txt", "w", encoding="utf-8") 
runner = unittest.TextTestRunner(stream=f, verbosity=2) 
runner.run(suite) f.close()

六、生成 HTMLTestRunner 测试报告

1 、复制 HTMLTestRunner.py 文件到项目文件夹;
2 、导入 HTMLTestRunner unittest 包;
3 、生成测试套件 suite = unittest.TestLoader().discover("./", "test*.py")
4 、以只写方式打开测试报告文件 f = open("test01.html", "wb")
5 、实例化 HTMLTestRunner 对象: runner = HTMLTestRunner(stream=f, title="
自动化测试报告 ", description="Chrome 浏览器 ")
参数说明:
stream open 函数打开的文件流;
title [ 可选参数 ] ,为报告标题;
description [ 可选参数 ] ,为报告描述信息;比如操作系统、浏览器等版本;
6 、执行: runner.run(suite)
7 、关闭文件;
1. 示例代码
import unittest
from HTMLTestRunner import HTMLTestRunner
suite = unittest.TestLoader().discover("./", "test*.py")
f = open("test01.html", "wb")
runner = HTMLTestRunner(stream=f, title="自动化测试报告",
description="Chrome 浏览器")
runner.run(suite)
f.close()

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值