自动化工具 (开源) XMind2TestCase:一个高效测试用例设计的解决方案!

Devin · 2019年01月02日 · 最后由 Devin 回复于 2019年01月21日 · 4266 次阅读
本帖已被设为精华帖!

XMind2TestCase 工具,提供了一个高效测试用例设计的解决方案!

一、背景

软件测试过程中,最重要、最核心就是测试用例的设计,也是测试童鞋、测试团队日常投入最多时间的工作内容之一。

然而,传统的测试用例设计过程有很多痛点:

  • 1、使用Excel表格进行测试用例设计,虽然成本低,但版本管理麻烦,维护更新耗时,用例评审繁琐,过程报表统计难...
  • 2、使用TestLink、TestCenter、Redmine等传统测试管理工具,虽然测试用例的执行、管理、统计比较方便,但依然存在编写用例效率不高、思路不够发散、在产品快速迭代过程中比较耗时等问题...
  • 3、公司自研测试管理工具,这是个不错的选择,但对于大部分小公司、小团队来说,一方面研发维护成本高,另一方面对技术要有一定要求...
  • 4、...

基于这些情况,现在越来越多公司选择使用思维导图这种高效的生产力工具进行用例设计,特别是敏捷开发团队。

事实上也证明,思维导图其发散性思维、图形化思维的特点,跟测试用例设计时所需的思维非常吻合,所以在实际工作中极大提升了我们测试用例设计的效率,也非常方便测试用例评审。

但是与此同时,使用思维导图进行测试用例设计的过程中也带来不少问题:

  • 1、测试用例难以量化管理、执行情况难以统计;
  • 2、测试用例执行结果与BUG管理系统难以打通;
  • 3、团队成员用思维导图设计用例的风格各异,沟通成本巨大;
  • 4、...

综合以上情况,我们可以发现不同的测试用例设计方式,各有各个的优劣。

那么问题来了,我们能不能将它们各自优点合在一起呢?这样不就可以提升我们的效率了!

于是,这时候 XMind2TestCase 就应运而生了,该工具基于 Python 实现,通过制定测试用例通用模板
然后使用 XMind 这款广为流传且开源的思维导图工具进行用例设计。
其中制定测试用例通用模板是一个非常核心的步骤(具体请看使用指南),有了通用的测试用例模板,我们就可以在 XMind 文件上解析并提取出测试用例所需的基本信息,
然后合成常见测试用例管理系统所需的用例导入文件。这样就将 XMind 设计测试用例的便利常见测试用例系统的高效管理结合起来了!

当前 XMind2TestCase 已实现从 XMind 文件到 TestLink 和 Zentao(禅道) 两大常见用例管理系统的测试用例转换,同时也提供 XMind 文件解析后的两种数据接口
(TestSuites、TestCases两种级别的JSON数据),方便快速与其他测试用例管理系统打通。

二、使用示例

1、Web工具示例

webtool

2、转换后用例预览

testcase_preview

3、TestLink导入结果示例

testlink

4、禅道(ZenTao)导入结果示例

zentao

三、安装方式

pip3 install xmind2testcase

四、版本升级

pip3 install -U xmind2testcase

五、使用方式

1、命令行调用

Usage:
xmind2testcase [path_to_xmind_file] [-csv] [-xml] [-json]

Example:
xmind2testcase /path/to/testcase.xmind => output testcase.csvtestcase.xmltestcase.json
xmind2testcase /path/to/testcase.xmind -csv => output testcase.csv
xmind2testcase /path/to/testcase.xmind -xml => output testcase.xml
xmind2testcase /path/to/testcase.xmind -json => output testcase.json

2、使用Web界面

web_tool_cli

Usage:
xmind2testcase [webtool] [port_num]

Example:
xmind2testcase webtool => launch the web testcase convertion tool locally -> 127.0.0.1:5001
xmind2testcase webtool 8000 => launch the web testcase convertion tool locally -> 127.0.0.1:8000

3、API调用

import json
import xmind
from xmind2testcase.zentao import xmind_to_zentao_csv_file
from xmind2testcase.testlink import xmind_to_testlink_xml_file
from xmind2testcase.utils import xmind_testcase_to_json_file
from xmind2testcase.utils import xmind_testsuite_to_json_file
from xmind2testcase.utils import get_xmind_testcase_list
from xmind2testcase.utils import get_xmind_testsuite_list


def main():
xmind_file = 'docs/xmind_testcase_template.xmind'
print('Start to convert XMind file: %s' % xmind_file)

zentao_csv_file = xmind_to_zentao_csv_file(xmind_file)
print('Convert XMind file to zentao csv file successfully: %s' % zentao_csv_file)

testlink_xml_file = xmind_to_testlink_xml_file(xmind_file)
print('Convert XMind file to testlink xml file successfully: %s' % testlink_xml_file)

testsuite_json_file = xmind_testsuite_to_json_file(xmind_file)
print('Convert XMind file to testsuite json file successfully: %s' % testsuite_json_file)

testcase_json_file = xmind_testcase_to_json_file(xmind_file)
print('Convert XMind file to testcase json file successfully: %s' % testcase_json_file)

testsuites = get_xmind_testsuite_list(xmind_file)
print('Convert XMind to testsuits dict data:\n%s' % json.dumps(testsuites, indent=2, separators=(',', ': '), ensure_ascii=False))

testcases = get_xmind_testcase_list(xmind_file)
print('Convert Xmind to testcases dict data:\n%s' % json.dumps(testcases, indent=4, separators=(',', ': ')))

workbook = xmind.load(xmind_file)
print('Convert XMind to Json data:\n%s' % json.dumps(workbook.getData(), indent=2, separators=(',', ': '), ensure_ascii=False))

print('Finished conversion, Congratulations!')


if __name__ == '__main__':
main()

4、XMind用例文件转为JSON数据

xmind_testcase_demo

(1)转为测试用例JSON数据
from xmind2testcase.utils import get_xmind_testcase_list
xmind_file = 'docs/xmind_testcase_demo.xmind'
testcases = get_xmind_testcase_list(xmind_file)
print(testcases)


Output:

[
{ # 测试用例
"name": "测试用例1", # 用例标题
"version": 1, # 用例版本
"summary": "测试用例1", # 用例摘要
"preconditions": "前置条件", # 前置条件
"execution_type": 1, # 用例执行类型(1:手动、2:自动)
"importance": 1, # 优先级(1:高、2:中、3:低)
"estimated_exec_duration": 3, # 预计执行时间(分钟)
"status": 7, # 用例状态(1:草稿、2:待评审、3:评审中、4:重做、5、废弃、6feature7:终稿)
"steps": [ # 测试步骤列表
{
"step_number": 1, # 编号
"actions": "测试步骤1", # 步骤内容
"expectedresults": "预期结果1", # 预期结果
"execution_type": 1 # 执行类型(1:手动,2:自动)
},
{
"step_number": 2,
"actions": "测试步骤2",
"expectedresults": "预期结果2",
"execution_type": 1
}
],
"product": "我是产品名", # 产品名称
"suite": "我是模块名(测试集1)" # 测试集(模块名)
},
{
"name": "测试用例2",
"version": 1,
"summary": "测试用例2",
"preconditions": "前置条件",
"execution_type": 1,
"importance": 1,
"estimated_exec_duration": 3,
"status": 7,
"steps": [
{
"step_number": 1,
"actions": "测试步骤1",
"expectedresults": "预期结果1",
"execution_type": 1
},
{
"step_number": 2,
"actions": "测试步骤2(预期结果2可以为空)",
"expectedresults": "",
"execution_type": 1
},
{
"step_number": 3,
"actions": "测试步骤3",
"expectedresults": "预期结果3",
"execution_type": 1
},
{
"step_number": 4,
"actions": "测试步骤4",
"expectedresults": "预期结果4",
"execution_type": 1
}
],
"product": "我是产品名",
"suite": "我是模块名(测试集1)"
},
{
"name": "测试用例3(测试步骤和预期结果可以都为空)",
"version": 1,
"summary": "测试用例3(测试步骤和预期结果可以都为空)",
"preconditions": "无",
"execution_type": 1,
"importance": 2,
"estimated_exec_duration": 3,
"status": 7,
"steps": [ ],
"product": "我是产品名",
"suite": "我是模块名(测试集1)"
},
{
"name": "测试步骤2(优先级默认为中)",
"version": 1,
"summary": "测试步骤2(优先级默认为中)",
"preconditions": "无",
"execution_type": 1,
"importance": 3,
"estimated_exec_duration": 3,
"status": 7,
"steps": [
{
"step_number": 1,
"actions": "测试步骤1",
"expectedresults": "预期结果1",
"execution_type": 1
},
{
"step_number": 2,
"actions": "测试步骤3",
"expectedresults": "",
"execution_type": 1
}
],
"product": "我是产品名",
"suite": "我是模块名(测试集2)"
},
{
"name": "测试用例3(前置条件默认为空) 无设置优先级,这里加入用例标题",
"version": 1,
"summary": "测试用例3(前置条件默认为空) 无设置优先级,这里加入用例标题",
"preconditions": "无",
"execution_type": 1,
"importance": 2,
"estimated_exec_duration": 3,
"status": 7,
"steps": [ ],
"product": "我是产品名",
"suite": "我是模块名(测试集2)"
}
]
(2)转为测试集JSON数据
from xmind2testcase.utils import get_xmind_testsuite_list
xmind_file = 'docs/xmind_testcase_demo.xmind'
testsuites = get_xmind_testsuite_list(xmind_file)
print(testsuites)


Output:

[
{ # XMind画布(Sheet)列表
"name": "我是产品名", # 产品名称
"details": null, # 产品摘要
"testcase_list": [], # 用例列表
"sub_suites": [ # 用例集列表
{
"name": "我是模块名(测试集1)", # 用例集1名称(模块名)
"details": null, # 用例集摘要
"testcase_list": [ # 用例列表
{ # 具体用例
"name": "测试用例1",
"version": 1,
"summary": "测试用例1",
"preconditions": "前置条件",
"execution_type": 1,
"importance": 1,
"estimated_exec_duration": 3,
"status": 7,
"steps": [
{
"step_number": 1,
"actions": "测试步骤1",
"expectedresults": "预期结果1",
"execution_type": 1
},
{
"step_number": 2,
"actions": "测试步骤2",
"expectedresults": "预期结果2",
"execution_type": 1
}
]
},
{
"name": "测试用例2",
"version": 1,
"summary": "测试用例2",
"preconditions": "前置条件",
"execution_type": 1,
"importance": 1,
"estimated_exec_duration": 3,
"status": 7,
"steps": [
{
"step_number": 1,
"actions": "测试步骤1",
"expectedresults": "预期结果1",
"execution_type": 1
},
{
"step_number": 2,
"actions": "测试步骤2(预期结果2可以为空)",
"expectedresults": "",
"execution_type": 1
},
{
"step_number": 3,
"actions": "测试步骤3",
"expectedresults": "预期结果3",
"execution_type": 1
},
{
"step_number": 4,
"actions": "测试步骤4",
"expectedresults": "预期结果4",
"execution_type": 1
}
]
},
{
"name": "测试用例3(测试步骤和预期结果可以都为空)",
"version": 1,
"summary": "测试用例3(测试步骤和预期结果可以都为空)",
"preconditions": "无",
"execution_type": 1,
"importance": 2,
"estimated_exec_duration": 3,
"status": 7,
"steps": []
}
],
"sub_suites": [] # 用例集中可以包含子用例集(目前只要产品类别下有用例集)
},
{
"name": "我是模块名(测试集2)", # 用例集2名称(模块名)
"details": "测试集摘要(详情)",
"testcase_list": [
{
"name": "测试步骤2(优先级默认为中)",
"version": 1,
"summary": "测试步骤2(优先级默认为中)",
"preconditions": "无",
"execution_type": 1,
"importance": 3,
"estimated_exec_duration": 3,
"status": 7,
"steps": [
{
"step_number": 1,
"actions": "测试步骤1",
"expectedresults": "预期结果1",
"execution_type": 1
},
{
"step_number": 2,
"actions": "测试步骤3",
"expectedresults": "",
"execution_type": 1
}
]
},
{
"name": "测试用例3(前置条件默认为空) 无设置优先级,这里加入用例标题",
"version": 1,
"summary": "测试用例3(前置条件默认为空) 无设置优先级,这里加入用例标题",
"preconditions": "无",
"execution_type": 1,
"importance": 2,
"estimated_exec_duration": 3,
"status": 7,
"steps": []
}
],
"sub_suites": []
}
]
}
]
(3)XMind文件转换为JSON数据

以上(1)TestCase数据、(2)TestSuite数据的获取,其实是基于XMind这个工具,对XMind文件进行解析和数据提取,然后转换而来。
这个工具是在设计XMind2TestCase时,针对XMind单独抽取出来的库,提供了XMind思维导图创建、解析、更新的一系列方法。使用它可以直接将XMind文件转换为JSON数据:

import xmind
xmind_file = 'docs/xmind_testcase_demo.xmind'
workbook = xmind.load(xmind_file)
data = workbook.getData()
print(data)


Output:

[
{ # XMind画布(sheet)列表
"id": "7hmnj6ahp0lonp4k2hodfok24f", # 画布ID
"title": "画布 1", # 画布名称
"topic": { # 中心主题
"id": "7c8av5gt8qfbac641lth4g1p67", # 主题ID
"link": null, # 主题上的超链接信息
"title": "我是产品名", # 主题名称
"note": null, # 主题上的备注信息
"label": null, # 主题上标签信息
"comment": null, # 主题上的批注(评论)信息
"markers": [], # 主题上的图标信息
"topics": [ # 子主题列表
{
"id": "2rj4ek3nn4sk0lc4pje3gvgv9k",
"link": null,
"title": "我是模块名(测试集1)", # 子主题1
"note": null,
"label": null,
"comment": null,
"markers": [],
"topics": [ # 子主题下的子主题列表
{
"id": "3hjj43s7rv66uncr1srl3qsboi",
"link": null,
"title": "测试用例1",
"note": "前置条件\n",
"label": "手动(执行方式默认为手动)",
"comment": null,
"markers": [
"priority-1"
],
"topics": [
{
"id": "3djn37j1fdc6081de319slf035",
"link": null,
"title": "测试步骤1",
"note": null,
"label": null,
"comment": null,
"markers": [],
"topics": [
{
"id": "7v0f1152popou38ndaaamt49l5",
"link": null,
"title": "预期结果1",
"note": null,
"label": null,
"comment": null,
"markers": []
}
]
},
{
"id": "2srtqqjp818clkk1drm233lank",
"link": null,
"title": "测试步骤2",
"note": null,
"label": null,
"comment": null,
"markers": [],
"topics": [
{
"id": "4jlbo280urmid3qkd01j7h8jnq",
"link": null,
"title": "预期结果2",
"note": null,
"label": null,
"comment": null,
"markers": []
}
]
}
]
},
...
]
},
...
]
}
}
]

具体参考:xmind_testcase_demo.json

四、自动化发布:一键打 Tag 并上传至 PYPI

每次在 __ about __.py 更新版本号后,运行以下命令,实现自动化更新打包上传至 PYPI ,同时根据其版本号自动打 Tag 并推送到仓库:

python3 setup.py pypi

upload_pypi

五、致谢

XMind2TestCase 工具的产生,受益于以下四个开源项目,并在此基础上扩展、优化,受益匪浅,感恩!

  • 1、XMind:XMind思维导图创建、解析、更新的一站式解决方案(Python实现)!
  • 2、xmind2testlink:践行了XMind通用测试用例模板设计思路,同时提供了Web转换工具!
  • 3、TestLink:提供了完整的测试用例管理流程和文档;
  • 4、禅道开源版(ZenTao):提供了完整的项目管理流程、文档和用户交流释疑群;

得益于开源,也将坚持开源,并为努力开源贡献自己的点滴之力。后续,将继续根据实际项目需要,定期进行更新维护,
欢迎大伙的使用意见反馈,谢谢!

(如果本项目对你有帮助的话,也欢迎 star

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 59 条回复 时间 点赞

欢迎使用和建议唷

厉害了,原来可以这样操作💪

挺不错一个方案,研究下看是否可以引入公司测试体系解决用例版本管理疼点。

你可以在这个方案上,继续进行扩展。可以线上 EXCEL 和 XMIND进行管理,目前我们自己平台就是结合了这两块。支持线下 ,线下,EXCEL 和XMIND 相互转换导入导出,同时支持导入到WEB 线上编写,评审,执行等。

九北鱼 回复

不错,有收获了,开源就是想听听大伙们的想法和建议

corre 回复

使用过程中,期待你的意见和建议😄

方案很好,但是感觉在我们团队,推行会很难……
不建议把详细的步骤写在xmind文件中,一个是xmind本身是思路的映射(大家一般画思维导图不会限制层级的,现在限死了,感觉失去了思维导图的一部分意义),再一个是,xmind当内容多了的话,会相当卡。楼主可以试试,当用例超过200条

Devin 回复

如果想支持导图在线编辑,推荐 百度的 kityminder-editor 。看到你这个就想起之前自己研究导图原理,从解析,到编辑,到导出各种过程。加油~
这里也有限制,就是得使用模板,不然数据无法按照规则获取

剪烛 回复

可以前期使用导图,就是编写测试功能点,随着项目成长,用例增长可以过渡为(自动化转换)使用EXCLE,编写详细测试用例。具体的方案还得以实际项目为主。

我觉得思维导图已经可以很好的实现用例的管理(增删改查),如果可以实现功能模块的管理,嵌入思维导图,并实现对用例、用例执行结果的统计分析,是最好的

Devin #11 · 2019年01月02日 作者
剪烛 回复

XMind2Testcase规则上没有层级限制,默认可以无限长,当遇到优先级标识时,才进入测试步骤和预期结果,如果没有优先级标识,所有层级作为测试标题

Devin #12 · 2019年01月02日 作者
剪烛 回复

的确超过200条Xmind使用比较卡,这边有超过400条多的情况。我们一般是两周一迭代敏捷开发,一个人负责一个产品,除了使用思维导图进行设计,其他Excel、测试管理系统效率都跟不上

Devin #13 · 2019年01月02日 作者
qixiafeng 回复

使用思维导图进行执行测试,标识执行结果,然后统计测试情况,这个后面我斟酌斟酌,感谢提供思路😄

Devin #14 · 2019年01月03日 作者
九北鱼 回复

思维导图的各种操作通过这个轻松解决了(https://testerhome.com/topics/17553),在线思维导图接下来也研究一下

恒温 将本帖设为了精华贴 01月03日 09:11
Devin 回复

优秀的设计,赞

这个方案挺好的

Devin #19 · 2019年01月03日 作者
Tony 回复

对我们这边也有不少帮助,欢迎试用哟

仅楼主可见

web这个只能在本机访问吗?我部署后无法在其他机器访问

Devin #22 · 2019年01月04日 作者
huang 回复

指定的是在禅道系统上导出乱码吗

Devin #23 · 2019年01月04日 作者
robert 回复

命令行启动默认部署在本地127.0.0.1,可以自行修改,建议拉取代码进行部署

牛人啊,高效率生产工具,我们决定已经准备用了!!!

Devin #25 · 2019年01月04日 作者
wolfgao 回复

归功于开源的力量,欢迎使用过程中的建议,接下来持续改进优化

请问可以部署到一台服务器上么?

Devin #27 · 2019年01月07日 作者
chrls.chen 回复

可以的,就是flask的简单部署方式,拉下代码就可以了

Devin #28 · 2019年01月07日 作者
chrls.chen 回复

代码里面也提供了简单的部署脚本

很棒,已经成功部署到服务器上了,默认部署的127.0.0.1可以使用Nginx配置代理地址实现访问,这样就不用改源码了😁

超级赞,但是优先级那没看懂,得自己下下来玩一把再说

好棒

给大佬递冰阔落🍼

Devin #33 · 2019年01月09日 作者
Bobby 回复

对的,服务端部署就是这个组合,妥妥的:Nginx + Supervisor + Gunicorn + Flask

Devin #34 · 2019年01月09日 作者
gallon 回复

优先级标识着测试用例标题的结束,接下来的内容就是测试步骤和预期结果;如果不添加优先级标识也可以,脑图链就都作为测试标题,因为脑图上部分测试用例是可以不需要测试步骤和预期结果的,从测试标题上我们就可以明确测试点

Devin #35 · 2019年01月09日 作者
张莹 回复

欢迎使用和建议😀

Devin #36 · 2019年01月09日 作者
panfeng 回复

来,一起干了🍻

37楼 已删除

今天使了一下,不好使,还不如excel表来的快,另外你这个xmind的软件是选哪个?怎么填写步骤,期望结果,预置条件等等?

Devin #39 · 2019年01月10日 作者
wolfgao 回复

XMind8,需要熟悉测试用例模板先,在使用指南上有详细说明

Devin #40 · 2019年01月10日 作者

今天更新到v1.3.0,支持测试用例执行结果标识、解析、统计,文档也已更新,欢迎试用(目前testlink、zentao新建测试用例时,无法导入用例结果,该更新主要用在自研用例管理系统用例统计)

Devin #41 · 2019年01月10日 作者

很不错的高效用例设计方式,准备引导实际项目中尝试,感谢开源!

Devin #43 · 2019年01月11日 作者
泪浔 回复

欢迎一起持续优化改进。

考虑很全面,我们公司目前也在搞这么一套东西,但是目前还是有不少问题。

主要是:
1:xmind 文件格式,不是文本格式,每次更新无法量化,不知道改了啥,无法做版本管理
2:转化为 km 的 json 格式后,使用百度开源框架来编辑 TC,样式丢失较多,导致多样化的标识,都需要重新开发~
3:如果说是需要导入其它系统里,不管是禅道还是 testlink,如果有更新,是直接重新导入吗?去重如何做?更新如何做?

Devin #45 · 2019年01月13日 作者
shadow 回复

1、目前这边的产品都处在快速迭代中,基本每个迭代都是新用例,后续计划在XMind上添加版本标识;
2、由于对前端不熟,百度开源脑图工具暂时研究不多,接下来也计划脑图web化;
3、无论在禅道、还是testlink,感觉更新都比较麻烦,后续考虑自研用例管理系统,现在这边基本都是新用例为主,所以还好点;
4、最后,可以优化的内容挺多,欢迎一起改进😄

仅楼主可见



@devin 我部署到linux,csv文件乱码呢?

Devin 回复

弱弱问下 flask的简单部署方式 具体命令是啥?

xmind中文转写乱码是操作什么问题吗?

mark一下 我也遇到转换后乱码

Caiwei 回复

使用最新的 xmind 软件,不要用那个 ZEN 的,应该就可以了

Devin #52 · 2019年01月15日 作者
拉宝 回复

在项目源码一个deploy.sh文件中

Devin #53 · 2019年01月15日 作者
shadow 回复

对,看了一下,XMind中的ZEN版本内部文件结构做了改变,大伙使用XMind经典系列就好,比如最新的XMind8

Devin #54 · 2019年01月15日 作者
拉宝 回复

导出的csv文件是utf-8格式,跟禅道需要的导入文件编码格式保存一致,之所以乱码是因为Excel默认打开不是使用utf-8格式,你改一下就好,不影响用例导入的

Devin #55 · 2019年01月15日 作者
shadow 回复

不错,有计划开源吗,学习学习

运行命令 xmind2testcase webtool 后一直停在那里,求教如何破解:

Devin #57 · 2019年01月16日 作者
fighting2022 回复

不需破解,这就是正常启动了,根据它的提示在浏览器上打开网址http://127.0.0.5001flask就好,有空也可以熟悉一下

@Devin 大佬能不能提个需求, Xmin文件转换的时候,case标题取值的时候能不能一关键字取啊 比如:TC:XXXX

Devin #59 · 2019年01月16日 作者
qa 回复

用例标题关键字取,具体指的是?

Devin 回复

是的

Devin #61 · 2019年01月21日 作者
huang 回复

禅道导出为utf-8时,会乱码;导出为gbk时,不会乱码;原因是因为Excel打开文件,默认使用gbk编码而已,修改一下编码方式就不会乱码了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册