重写ddt的mk_test_name方法
一. 测试用例名字的问题
使用ddt做测试,得到的测试报告中,测试用例的名字默认以_01, _02, _03...递增的形式结尾,这时我希望用例名能够以_api_name结尾,比如注册模块,希望看到的形式是test_send_requests_01_register...
这个问题如何解决呢

二. 方法重写(这个重写是在源码的基础上)
这个方法是从 python ddt 重写 看到的,ddt.mk_test_name重写前的方法为
# Add zeros before index to keep order
index = "{0:0{1}}".format(index + 1, index_len)
if not is_trivial(value):
return "{0}_{1}".format(name, index)
try:
value = str(value)
except UnicodeEncodeError:
# fallback for python2
value = value.encode('ascii', 'backslashreplace')
test_name = "{0}_{1}_{2}".format(name, index, value)
return re.sub(r'\W|^(?=\d)', '_', test_name)
重写后的方法为
# Add zeros before index to keep order
index = "{0:0{1}}".format(index + 1, index_len)
if not is_trivial(value):
if type(value) is dict and "api_name" in value.keys():
value = value["api_name"]
else:
return "{0}_{1}".format(name, index)
try:
value = str(value)
except UnicodeEncodeError:
# fallback for python2
value = value.encode('ascii', 'backslashreplace')
test_name = "{0}_{1}_{2}".format(name, index, value)
return re.sub(r'\W|^(?=\d)', '_', test_name)
三. 原理分析
本段主要参考《ddt源码修改:HtmlTestRunner报告依据接口名显示用例名字》
"查看了ddt源码之后,发现有个函数是用来生成测试用例名字的。这个函数叫:mk_test_name
它是如何来生成测试用例名字的呢?
它接受两个参数:name 和 value.
- name:为单元测试中,测试用例的名字。即test_api
- value:为测试数据。ddt是处理一组测试数据。而这个value就是这一组数据中的每一个测试数据
对value的值是有限制的:要么就是单值变量,要么就是元组或者列表并且要求元组和列表中的数据都是单值变量。如("name","port") 、["name","port"]
如果传进来的测试数据,不符合value的要求,那么测试用例名字为:name_index
如果传进来的测试数据,符合value的要求,那么测试用例名字为:name_index_value。如果value为列表或者元组,那么将列表/元组的每个数据依次追加在末尾
比如传进来的name值为test_login,value值为["name","port"]。那最终的测试用例名字是:test_login_01_name_port
如果传进来的name值为test_login,value值为{"name":"login","port":2204},那最终的测试用例名字为:test_login_01。因为它不支持对字典类型的数据处理
很不巧,我的接口自动化框架中,ddt处理的数据是一列表:列表当中每个数据都为字典。ddt一遍历整个列表,那传给value的值刚好是字典。。
so。。。我得到的测试用例名称就是:test_api_01,test_api_02,test_api_03..........test_api_0N
ddt源码如下(红色粗体部分标识):
def mk_test_name(name, value, index=0):
"""
Generate a new name for a test case.
It will take the original test name and append an ordinal index and a
string representation of the value, and convert the result into a valid
python identifier by replacing extraneous characters with ``_``.
We avoid doing str(value) if dealing with non-trivial values.
The problem is possible different names with different runs, e.g.
different order of dictionary keys (see PYTHONHASHSEED) or dealing
with mock objects.
Trivial scalar values are passed as is.
A "trivial" value is a plain scalar, or a tuple or list consisting
only of trivial values.
"""
# Add zeros before index to keep order
index = "{0:0{1}}".format(index + 1, index_len)
if not is_trivial(value): #如果不符合value的要求,则直接返回用例名称_下标作为最终测试用例名字。
return "{0}_{1}".format(name, index)
try:
value = str(value)
except UnicodeEncodeError:
# fallback for python2
value = value.encode('ascii', 'backslashreplace')
test_name = "{0}_{1}_{2}".format(name, index, value)
return re.sub(r'\W|^(?=\d)', '_', test_name)
为了让我的测试报告,呈现的更好。那就改改ddt源码,让它能够适应我的框架。
考虑两个问题:
1、不同接口的测试用例名字如何来??
2、如何让ddt支持对字典的处理??
解决方法:
第一个问题:每一个测试用例主动提供一个用例名字,说明你是什么接口的什么场景用例。比如:接口名_场景名。login_success、login_noPasswd、login_wrongPasswd等。在我的框架当中,每一个测试用例是一个字典。那么我就在字典中添加一个键值对,case_name=用例名称
第二个问题:在ddt中添加对字典的处理,如果字典中有case_name字段,则将字典中键名为case_name的值作为测试用例名称中的value值
修改后的ddt源码为(红色粗体部分为修改的内容):
def mk_test_name(name, value, index=0):
print("-------first value------------")
print(value)
# Add zeros before index to keep order
index = "{0:0{1}}".format(index + 1, index_len)
#添加了对字典数据的处理。
if not is_trivial(value) and type(value) is not dict:
return "{0}_{1}".format(name, index)
#如果数据是字典,则获取字典当中的api_name对应的值,加到测试用例名称中。
if type(value) is dict:
try:
value = value["case_name"] #case_name作为value值
except:
return "{0}_{1}".format(name, index)
try:
value = str(value)
except UnicodeEncodeError:
# fallback for python2
value = value.encode('ascii', 'backslashreplace')
test_name = "{0}_{1}_{2}".format(name, index, value)
return re.sub(r'\W|^(?=\d)', '_', test_name)
"
四. 运行效果

参考文章
http://www.cnblogs.com/za0909/p/9129745.html
https://www.cnblogs.com/Simple-Small/p/9230382.html
重写ddt的mk_test_name方法的更多相关文章
- web自动化 -- HTMLreport(一)测试报告自定义测试用例名,重写ddt
一.需求痛点 1.HTMLreport测试报告的用例名不明确 2.希望可以自定义HTMLreport测试报告的用例名 3.痛点截图 二.解决办法 1.原因分析 HTMLreport测试报告中的用例名是 ...
- 重写jquery的ajax方法
//首先备份下jquery的ajax方法 var _ajax=$.ajax; //重写jquery的ajax方法 $.ajax=function(opt){ //备份opt中error和success ...
- 子类可以有跟父类中同名的方法,但是会重写父类中的方法,甚至是root class中的方法
/* 子类可以重写父类中的方法,甚至是root class中的方法,比如NSObeject 的new方法,但是后提示警告如下 Method is expected to return an insta ...
- 如何真正重写window对象的方法
重写window对象的方法不是一件新奇的事,比如我们可能需要改变默认alert的行为,如何安全的重写呢? 小菜看到某知名IT网站是这样的写法: window.alert = function(){}; ...
- Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)
Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例 原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...
- 重写 button 的创建方法
重写 button 的创建方法 //sxc时时改变 // self.videoM.progress = progress; // if ([self.videoM.downloadStr isEqua ...
- java集合框架(hashSet自定义元素是否相同,重写hashCode和equals方法)
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不一致,元素不可以重复 * (通过哈希值来判断是否是同一个对象) * ----HashSet:底层数据结构是哈希表, * 保证 ...
- java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样
一.在Object类中的定义为:public native int hashCode();是一个本地方法,返回的对象的地址值.但是,同样的思路,在String等封装类中对此方法进行了重写.方法调用得到 ...
- 为什么要重写 hashcode 和 equals 方法?
引言 以前面试的时候被面试官问到过这样一个问题: 你有没有重写过 hashCode 方法? 心里想着我没事重写哪玩意干啥,能不写就不写.嘴上当然没敢这么说,只能略表遗憾的说抱歉,我没写过. 撇了面试官 ...
随机推荐
- 2014-08-28——移动端web开发,基本Meta标签
1.<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scal ...
- Redis3.2.5配置主从服务器遇到的一些错误
注意:关闭主从服务器的防火墙 问题一: WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net ...
- issubclass/type/isinstance、函数和方法、反射、callable、特殊成员补充
一.issubclass/type/isinstance(***) 1.issubclass(参数1, 参数2):检查第一个参数是否是第二个参数的 子子孙孙类,如下示例: class Base(obj ...
- android自定义View (五)view.requestLayout() 与 invalidate()
一.要点 If in the course of processing the event, the view's bounds may need to be changed, the view wi ...
- MVC4 中使用 Area 和 注意的地方
在MVC项目中经常会使用到Area来分开不同的模块让项目结构更加的清晰. 步骤如下: 项目 –> 添加 -> 区域 (Area) 输入 Admin 添加成功后 Area包含:创建一个空 ...
- Loadrunder脚本篇——web_custom_request做接口测试
一.POST + JSON格式参数 例: web_custom_request("create", "URL=http://xxx.xxx.x.xx:1600/ditui ...
- Kafka Confluent
今天我们要讲的大数据公司叫作Confluent,这个公司是前LinkedIn员工出来后联合创办的,而创业的基础是一款叫作Apache Kafka的开源软件. Confluen联合创始人Jun Rao即 ...
- $Android连续按返回键两次实现退出程序
思路:重写Activity的onKeyDown方法,判断按键是不是返回键,如果是,则再判断按下的时间和上次按下的时间之间的差值(毫秒数)是不是大于2000,如果不大于,则用finish()方法结束程序 ...
- 每日练习level-7
1.有序列表.无序列表.自定义列表如何使用?写个简单的例子.三者在语义上有什么区别?使用场景是什么? 能否嵌套? 有序列表是一列使用数字进行标记的项目,它使用<li>包含于<ol&g ...
- Linux 调优
一.系统优化 1.硬件优化 增加内存 更换速度跟高磁盘(sata->sas)可以增加固态硬盘 更换更高校率的网卡,或者双网卡绑定,两个网卡作为一个网卡使用.服务器网卡一般为千兆 2.系统层优化 ...