四、浅谈 unittest 框架

1.分层模型:

  (1)页面元素处理层:即 Page Object(PO模式)表示页面对象管理,将每个页面上所有元素定义在一个模块中,便于维护脚本。

  (2)业务流操作层:基于页面元素处理层实现业务流的自由组织,对应自动化测试的业务流场景的执行测试用例。

  (3)测试用例层:根据业务流场景设计相应的测试用例并执行,用例的执行都是通过框架完成(如:unittest、pytest),可以很好组织测试用例的执行并分析结果。

  (4)数据分离层:将脚本中的所有数据提取出来进行专门的数据模块管理,后期直接修改相应数据即可,不需要进行底层代码的查看分析。

  (5)公共层:进行常量数据的存储、报告的生成、日志的保存、邮件的发送等。

  (6)主程序入口应用层:设定主程序入口。

 

2.Page Object 模式优点:

  (1)PO 模式实现了页面元素的独立管理,实现页面元素与业务流的分离;

  (2)在用例层可以自由组织各个业务操作,提高了其页面元素的方法及页面业务的方法的可复用性;

 

3. unittest 框架:

  unittest 框架主要构成:TestCase、TestSuite、TestRunner、TestFixture

  TestCase:测试用例,对应一个完整的业务流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),测试后环境还原(tearDown),一个用例表示一个完整业务。

  TestSuite:一组测试用例的集合,可以以模块化的形式实现用例,以测试类的形式组织用例。

  TestRunner:测试运行器,定义执行测试用例的方式

  TestFixture:测试固件(夹具),完成某些对象初始化操作,即测试用例运行所需的环境搭建和销毁操作。

  

  unittest 框架测试流程:

    定义好 TestCase,由 TestLoader 加载 TestCase 到 TestSuite 中,再由 TextTestRunner 来运行 TestSuite,运行结果保存到 TextTestResult 中,最后通过 unittest.main() 完成测试用例的执行。

 

4. unittest 框架常用断言:

  assertEqual(arg1, arg2, msg=None):验证 arg1 = arg2 是否成立,不成立则 fail

  assertTrue(expr, msg=None):验证 expr,如果为 false,则 fail

  assertIs(arg1, arg2, msg=None):验证arg1,arg2 是否是同一个对象,不是则 fail

  assertIsInstance(arg1, arg2):验证 arg1 与 arg2 的实例对象是否相同,不是则 fail

 

5. unittest 框架中的 testfixture:

  testfixture:实现整个测试中所有用例所需要资源的管理操作,如资源(文件流、数据库资源、驱动器对象等)创建、销毁等。

  testfixture 主要由两个方法构成:setUp(创建)、tearDown(销毁),方法名固定,严格区分大小写。

  serUp():每个测试用例执行之前都会执行一次

  tearDown():每个测试用例执行完毕之后都会执行一次

  

  @classmethod

  serUpClass():在所有测试用例执行之前仅执行一次

  tearDownClass():在所有测试用例执行之后仅执行一次,

 

6. unittest 框架实现参数化 --ddt

  ddt:表示数据驱动测试,用于实现测试用例参数化的一种实现方式

  ddt 提供了一个类装饰器 @ddt,提供了两个方法装饰器 @data、@file_data

  多种参数类型的数据结构传入:

    (1)单一型数据结构:无论传入的数据是何种类型,都当做一个值处理。

    (2)复合数据类型结构处理(list、tuple、dict):需添加一个装饰器 @ddt.unpack

代码举例:  

import unittest
from ddt import ddt, data, unpack


def add(a, b):
return a + b


@ddt
class TestDemo(unittest.TestCase):
# data 可传递元组
@data((1, 2, 3))
def test_01(self, a):
print(a)
print(type(a))

# data 可传递列表,通过索引取值
@data([1, 2, 3])
def test_02(self, b):
print(b[0])
print(type(b))

# 使用 unpack 拆分数据 data 传递的列表(元组),使用形参接收,形参个数需与列表长度相同否则报错
@data([1, 2, 3])
@unpack
def test_03(self, a, b, c):
print(a)
print(b)
print(c)

# unpack 拆包字典,使用形参接收,形参名需与字典 key 相同否则报错
@data({"a": 1, "b": 2, "expect": 3}, {"a": 33, "b": 2, "expect": 35})
@unpack
def test_04(self, a, b, expect):
print(a)
print(b)
print(expect)
self.assertEqual(add(a, b), expect)


if __name__ == '__main__':
unittest.main()

 

posted @   努力的小测试  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示