一种数据与逻辑分离的Python单元测试工具

几个概念

TestCase

TestCase是一个完整的测试单元,最小的测试执行实体,就是我们常说的测试用例。

TestSuite

以某种特性将测试用例组合到一起的测试用例集合被称作TestSuite,中文可以叫做测试套件。TestSuite可以包含TestCase,也可以嵌套TestSuite。

TestFixtrue

TestFixtrue是测试主程序运行时所需要的一切东西,可能是数据,可能是系统环境,也有可能是某个具体实例化类,中文可以称作测试固件。TestFixtrue包括构建(setUp)和销毁(tearDown)两个部分。例如,某个测试用例需要访问数据库,那么可以在setUp中建立数据库连接并初始化相关数据,在tearDown中释放数据库连接并还原相关数据。此外,TestFixtrue既可以存在于测试用例层面,也可以存在于测试套件层面。

单元测试框架

结合以上概念,一个测试用例的执行过程包括:

  • 测试用例固件构建
  • 执行测试用例主程序
  • 测试用例固件销毁

一个测试套件的执行过程包括:

  • 测试套件固件构建
  • 测试用例1固件构建
  • 执行测试用例1主程序
  • 测试用例1固件销毁
  • 测试用例2固件构建
  • ……
  • 测试用例n固件销毁
  • 测试套件固件销毁

常用的单元测试工具

Python下常用的单元测试工具有unittest,PyUnit,nose。这三种工具的实现原理和使用方式大致相同。下面以unittest为例,来观察这些工具的特点。

import unittest
class CaculateTestCase(unittest.TestCase):
def setUp(self):
self.a = 1
self.b = 2
print 'set up the fixture'
def tearDown(self):
self.a = None
self.b = None
print 'tear down the fixture'
def testAdd(self):
assert (self.a+self.b) == 3, 'add function error'
def testMinus(self):
assert (self.a-self.b) == -1, 'minus function error'
if __name__ == '__main__':
unittest.main()

在上面的代码中,CaculateTestCase是有关运算的TestCase,它继承自unittest.TestCase类。CaculateTestCase重写了setUp和tearDown方法,分别对应fixture的构建和销毁代码。

在加载测试任务时,unittest会根据目标文件寻找unittest.TestCase的子类,并寻找以“test”开头的方法,这些方法分别对应一个测试用例主程序。

因此,CaculateTestCase的具体执行流程是:

  • 执行CaculateTestCase中的setUp方法,进行固件构建
  • 依次执行CaculateTestCase中以“test”开头的方法,即testAdd和testMinus方法
  • 执行CaculateTestCase中的tearDown方法,进行固件销毁

分离数据与逻辑

在CaculateTestCase实例中,a和b变量是写死在程序中,脚本显得相当死板,没有什么可重用性。若让数据在以单一的文件存在,CaculateTestCase中只包含逻辑程序,测试工具在执行用例时,会根据数据文件初始化实例变量。如此一来,分离了数据和逻辑,逻辑部分变得可重用,可定制。在经过这般处理后,一个测试用例划分为测试用例逻辑程序测试用例数据两个部分。在这里,我将测试用例逻辑程序抽象为TestDriver,即测试驱动器,而测试用例数据称作TestParam,即测试驱动数据。

TestDriver

与unittest等单元测试工具不同的是,我并没有将测试固件和主程序代码放在一个文件中或类中,而是用三个文件分别存放————setUp.py,tearDown.py,exec.py,并通过传递实例变量来共享TestCase实例。

因此,TestDriver的示例代码如下:

setUp.py代码:

def  setUp(tc):
#固件构建代码
Pass

tearDown.py代码:

def  tearDown (ts):
#固件构建代码
Pass

exec.py 代码:

def  tc_case1 (tc):
#case1的测试逻辑代码
pass
def tc_case2(tc):
#case2的测试逻辑代码
pass
#……
def tc_caseN(tc):
#caseN的测试逻辑代码
pass

此外,TestDriver还包括默认的驱动参数信息,param.json,示例如下:

{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}

TestCase

抽象出TestDriver后,在定义一个TestCase时不需要再写测试程序,而是指定一个TestDriver和TestParam,TestCase的示例文件如下:

{
"TestCase":"caseName",
"TestDriver": "dirverName",
"TestParam": {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
}

TestPlan

为了更好地组织TestCase故提出TestPlan这一概念,在执行完TestPlan后,会生成测试报告,发送测试通知。示例如下:

{
"TestPlan":"planName",
"CaseList":"tc_case1,tc_case2,tc_case3",
"EmailList":"xx@xx,xxx@xx",
"Crontab":"xxx"
}

CaseList即TestPlan所包含的TestCase,EmailList即TestPlan执行完毕后接收通知的邮箱信息,Crontab即TestPlan的定时器执行的crontab配置。

TestLib

当测试逻辑比较复杂时,TestDriver中代码可能也随之变得复杂。这时需要提供一完善的Python测试库,所有的业务操作均在测试库中,TestDriver只需要引用测试库进行业务操作,不包含业务逻辑的具体实现程序。随着TestLib的不断丰富,TestDriver中内容越来简明清晰,构建一个TestDriver也变得简单。于此,测试工作变得简单和更容易维护。

总结

“driver-case-plan”这种测试概念模型是对传统的单元测试框架的一种泛化抽象,它使得case在一定程度上更将通用,不受测试类型和业务类型的限制。此外,由于TestDriver的setUp、tearDown和exec是三个独立的文件,而不是像传统的单元测试工具这三部分是融合在一个文件中,在Web化时很难用一个单一的字段存储各部分的代码。再加上,TestCase和TestPlan也是JSON格式的文件,这是不是意味着该工具更容易Web化?在添加TestDriver后,TestCase和TestPlan的相关操作(添加用例计划、执行用例计划等)只需要在Web端处理即可?是不是可以依据该工具很容易地实现一个通用的CASE管理平台?

一种数据与逻辑分离的Python单元测试工具的更多相关文章

  1. 转载-使用 Feed4JUnit 进行数据与代码分离的 Java 单元测试

    JUnit 是被广泛应用的 Java 单元测试框架,但是它没有很好的提供参数化测试的支持,很多测试人员不得不把测试数据写在程序里或者通过其它方法实现数据与代码的分离,在后续的修改和维护上有诸多限制和不 ...

  2. Python单元测试工具doctest和unittest

    Python标准库包含两个测试工具. doctest:一个简单的模块,为检查文档而设计,但也适合用来编写单元测试. unittest:一个通用的测试框架. 一.使用doctest进行单元测试 创建文件 ...

  3. Javascript模板及其中的数据逻辑分离思想(MVC)

    #Javascript模板及其中的数据逻辑分离思想 ##需求描述 项目数据库的题目表描述了70-120道题目,并且是会变化的,要根据数据库中的数据描述,比如,选择还是填空题,是不是重点题,题目总分是多 ...

  4. 记一次数据、逻辑、视图分离的原生JS项目实践

    一切的开始源于这篇文章:一句话理解Vue核心内容. 在文章中,作者给出了这样一个思考: 假设现在有一个这样的需求,有一张图片,在被点击时,可以记录下被点击的次数. 这看起来很简单吧, 按照上面提到到开 ...

  5. Python中xml、字典、json、类四种数据的转换

    最近学python,觉得python很强很大很强大,写一个学习随笔,当作留念注:xml.字典.json.类四种数据的转换,从左到右依次转换,即xml要转换为类时,先将xml转换为字典,再将字典转换为j ...

  6. 基于Python接口自动化测试框架+数据与代码分离(进阶篇)附源码

    引言 在上一篇<基于Python接口自动化测试框架(初级篇)附源码>讲过了接口自动化测试框架的搭建,最核心的模块功能就是测试数据库初始化,再来看看之前的框架结构: 可以看出testcase ...

  7. 解析大型.NET ERP系统 界面与逻辑分离

    Windows Forms程序实现界面与逻辑分离的关键是数据绑定技术(Data Binding),这与微软推出的ASP.NET MVC的原理相同,分离业务代码与界面层,提高系统的可维护性. 数据绑定 ...

  8. mysql中的优化, 简单的说了一下垂直分表, 水平分表(有几种模运算),读写分离.

    一.mysql中的优化 where语句的优化 1.尽量避免在 where 子句中对字段进行表达式操作select id from uinfo_jifen where jifen/60 > 100 ...

  9. Jmeter(七)Jmeter脚本优化(数据与脚本分离)

    午休时间再来记一记,嗯..回顾着使用Jmeter的历程,想着日常都会用到的一些功能.一些组件:敲定了本篇的主题----------是的.脚本优化. 说起脚本优化,为什么要优化?又怎么优化?是个永恒的话 ...

随机推荐

  1. 工作随笔——jasypt-spring-boot使用

    最近有一个项目,要求对各种配置文件中的数据进行加密.so,let`s do it. Maven依赖 <dependency> <groupId>com.github.ulise ...

  2. 多命令顺序执行,dd命令,管道|,grep,通配符,其他特殊符号

    多命令顺序执行:命令1;命令2 命令之间没有逻辑关系 命令1&&命令2 命令1执行正确才执行命令2,命令1执行错误不会执行命令2 命令1||命令2 命令执行错误才执行命令2,命令1执行 ...

  3. Charles 抓包工具使用部分问题总结

    一. You may need to configure your browser or application to trust the Charles Root Certificate. See ...

  4. 通过 Sublime Package Control 安装插件后不能用的解决办法

    最近使用 Sublime 写 SASS 的时候需要使用高亮功能,通过 Package Control 安装了相关插件,但是安装之后没有反应,再次打开 Package Control 的时候,已经搜索不 ...

  5. 关于C++函数返回局部对象的详细分析

    以前一直挺好奇的,C++是怎么在函数内返回一个局部对象的.因为按照我之前的想法,函数返回一个基本类型的值是通过存放到ecx实现的(关于浮点不了解),但是局部对象又是比较大的,很明显不能使用寄存器作为通 ...

  6. 搭建lnmp教程

    LNMP指的是一个基于CentOS/Debian 上安装Nginx.PHP.MySQL.php.可以在独立主机上轻松的安装LNMP生产环境. 1 安装nginx 如果是一台新的服务器可直接安装(若以前 ...

  7. Git详解之三:Git分支

    Git 分支 几乎每一种版本控制系统都以某种形式支持分支.使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作.在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的 ...

  8. [HNOI2008]Cards

    题目描述 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案. 进一步,小春要求染出Sr张红色,Sb张蓝 ...

  9. Vuejs之开发环境搭建

    Vue.js Vue.js是目前很火的一个前端框架,采用MVVM模式设计,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能够快 ...

  10. Fiddler中设置断点修改返回结果Response

    测试有时会遇到需要测试返回不同的数据前端展示出来会如何?如果去数据库中的数据会比较麻烦.这样我们可以通过fiddler设置断点来修改返回的数据实现测试不同的数据展示. 1.设置断点 (1)点击菜单栏按 ...