将 XMind 测试用例转换为 CSV 文件导入测试管理平台

news/2025/10/18 17:40:39/文章来源:https://www.cnblogs.com/testero/p/19139053

在日常的软件测试工作中,我们常常使用 XMind 来整理测试用例。XMind 的可视化结构让用例层次清晰、逻辑直观,但当我们需要将这些用例导入到测试管理平台(如 TestRail、禅道、Jira 等)时,就需要把它们转换成 CSV 文件。本文就分享一个简单易行的方法。


为什么需要转换

  1. 批量导入:测试管理平台通常支持 CSV 批量导入,避免重复手动录入。
  2. 结构清晰:XMind 中的测试用例按模块、功能、子功能组织,转换成 CSV 后便于统一管理。
  3. 提高效率:特别是面对上百条用例时,自动化转换节省大量时间。

说明

这里我用到的xminf版本是图中这个,其他版本自测
image

准备工作

  • XMind 文件:确保你的测试用例已经整理好,最好按照模块-功能-用例步骤的层级结构。

操作步骤

1. XMind文件格式

目前脚本按这个格式处理的,可以根据自己的需求部分代码
image

2. 编写转换脚本

用 Java 可以快速把文本解析成 CSV,例如:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opencsv.CSVWriter;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;public class XmindToCsvConverter {public static void main(String[] args) throws Exception {// XMind 文件路径String xmindFile = "/Users/xx.xmind";convertXmindToCsv(xmindFile);}public static void convertXmindToCsv(String xmindFile) throws Exception {// 1. 解压 XMind 并读取 content.jsonString jsonContent = extractJsonFromXmind(xmindFile);ObjectMapper objectMapper = new ObjectMapper();JsonNode rootNode = objectMapper.readTree(jsonContent);// 获取根节点的名称,作为 CSV 文件名String rootTitle = rootNode.get(0).get("rootTopic").get("title").asText();// 确定 CSV 文件路径(与 XMind 文件同目录)Path xmindPath = Paths.get(xmindFile);// 获取 XMind 所在目录String outputDir = xmindPath.getParent().toString();// 生成 CSV 文件路径String outputCsv = outputDir + "/用例csv/" + rootTitle + ".csv";System.out.println("CSV文件名: " + outputCsv);// 2. 解析 JSON 生成测试用例List<String[]> testCases = new ArrayList<>();// CSV 表头testCases.add(new String[]{"模块", "用例标题", "前置条件", "步骤ID", "步骤", "预期结果"});// 变量存储上一个节点信息AtomicReference<String> lastModule = new AtomicReference<>("");AtomicReference<String> lastCaseTitle = new AtomicReference<>("");AtomicReference<String> lastPrecondition = new AtomicReference<>("");AtomicReference<Boolean> isFirstStep = new AtomicReference<>(true);// 遍历 XMind 结构for (JsonNode sheet : rootNode) {traverseNode(sheet.get("rootTopic"), new ArrayList<>(), testCases, lastModule, lastCaseTitle, lastPrecondition, isFirstStep);}// 3. 保存到 CSV 文件try (CSVWriter writer = new CSVWriter(new FileWriter(outputCsv))) {writer.writeAll(testCases);}System.out.println("转换完成: " + outputCsv);}private static String extractJsonFromXmind(String xmindFile) throws IOException {try (ZipFile zipFile = new ZipFile(xmindFile)) {for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) {ZipEntry entry = entries.nextElement();if (entry.getName().endsWith("content.json")) {try (InputStream is = zipFile.getInputStream(entry);Scanner scanner = new Scanner(is, "UTF-8")) {return scanner.useDelimiter("\\A").next();}}}}throw new FileNotFoundException("content.json not found in XMind file");}private static void traverseNode(JsonNode node, List<String> path, List<String[]> testCases, AtomicReference<String> lastModule, AtomicReference<String> lastCaseTitle, AtomicReference<String> lastPrecondition, AtomicReference<Boolean> isFirstStep) {if (node == null || !node.has("title")) return;List<String> newPath = new ArrayList<>(path);newPath.add(node.get("title").asText());if (node.has("children")) {for (JsonNode child : node.get("children").get("attached")) {traverseNode(child, newPath, testCases, lastModule, lastCaseTitle, lastPrecondition, isFirstStep);}} else {int size = newPath.size();String module = size >= 3 ? String.join("-", newPath.subList(0, 3)) : "";String caseTitle = size >= 4 ? newPath.get(3) : "";boolean hasPrecondition = (size == 8);String precondition = hasPrecondition ? newPath.get(4) : "";String stepId = hasPrecondition ? newPath.get(5) : (size >= 5 ? newPath.get(4) : "");String step = hasPrecondition ? newPath.get(6) : (size >= 6 ? newPath.get(5) : "");String expectedResult = hasPrecondition ? newPath.get(7) : (size >= 7 ? newPath.get(6) : "");// 用例的第一步保留模块名称if (caseTitle.equals(lastCaseTitle.get())) {caseTitle = "";precondition = "";if (!isFirstStep.get()) {module = "";}} else {lastCaseTitle.set(caseTitle);lastPrecondition.set(precondition);// 新用例的第一步isFirstStep.set(true);}testCases.add(new String[]{module, caseTitle, precondition, stepId, step, expectedResult});// 之后的步骤不再显示模块isFirstStep.set(false);}}
}

提示:根据实际导出的文本格式,可能需要调整解析逻辑。

3. 导入到测试管理平台

  • 打开平台的导入功能 → 选择 CSV 文件 → 映射字段 → 批量导入。
  • 导入完成后,检查用例层级和步骤是否正确。

总结

将 XMind 测试用例转换为 CSV 文件并导入测试平台,虽然看似多了一步,但合理利用脚本工具和平台导入功能,可以极大提升效率,减少重复劳动。对于日常测试工作来说,这是一项值得掌握的小技巧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/939702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

互评-OO之接口-DAO模式代码阅读及应用

集美大学课程实验报告-互评-OO之接口-DAO模式代码阅读及应用项目名称 内容课程名称 Java班级 网安2413指导教师 郑如滨学生姓名 林沁茹学号 202421336067实验项目名称 互评-OO之接口-DAO模式代码阅读及应用上机实践日期…

【为美好CTF献上祝福】unity逆向

咕咕,有点懒,以后再更 当你正在做一道逆向题,下载文件后发现得到一个unity文件,此时你应该: 第一步:判断

今日学习笔记

AI 学习与人脑类比总结文档 一、AI 与人类学习的本质 • 共同点:无论是人类大脑还是人工神经网络,本质上都是在寻找并逼近输入与输出之间的复杂映射函数。 • 人类学习:通过感官获取信息 → 在大脑形成突触连接 → …

CSP-S 2022 Solution

CSP-S 2022 题解报告\[『山鸟与鱼不同路,从此山水不相逢。莫问故人长短痛,昨夜星辰皆随风』 \]\[\LARGE CSP-S\ \ 2022 题解报告\\ Author : Floyd.Uranus \]题目 假期计划 策略游戏 星战 数据传输算法概览 \(贪心,…

印刷电子技术挑战传统PCB主导地位

荷兰初创企业TracXon获得475万欧元种子轮融资,致力于推广混合印刷电子技术。该技术通过卷对卷制造工艺直接在可回收薄膜上印刷电路,无需铜材、焊料或有毒化学品,可降低80%碳排放,目标在2033年前替代至少10%的传统印…

2025-10-18

2025-10-18verilator的赋值也是有时序的,在调用top->eval()前用所用的verilog的输出都是旧值。另外ELF文件结构这块还是需要看一下的,例如看一下《程序员的自我修养》这本书

某兔网站加密学习

声明:本文仅作学习交流,请遵守法律法规,不要恶意爬取网站 某兔快递单号查询抓接口,发现载荷里面有一个S参数非常神秘正常断点跟堆栈发现是异步操作,一步步跟进,发现走到了app开头的这个JS中。 搜索:e.s = a.cre…

5.vtk学习——点云显示进阶

介绍 承接上文,介绍下面的显示效果如何实现。如果能理解之前的内容,这里的思路是很自然的。三角化会把点相连创建出一个个三角面。这个三角面不就是需要显示的拓扑结构吗。 从Halcon里面获取到三角化后创建的三角形数…

[LangChain] 03. 缓存

在实际开发 AI 应用的过程中,我们经常会遇到重复输入的情况:同一用户多次询问相同的问题 刷新页面或误触按钮触发了相同请求 不同用户提出了内容高度相似的问题如果每次都让大模型重新生成响应,不仅效率低下,还会带…

面试 / 答辩总卡壳?这款 AI 面试辅助新功能:上传专属资料,精准应答不翻车

你是否曾在面试或答辩时,被一个冷不防的细节问题问倒?明明资料里写过,临场却大脑空白。现在,这个问题有了全新的解决方案。AI面试助手“面试精灵”正式推出“知识库文档”功能,它能将你的百页文档变成AI的“外挂大…

081_尚硅谷_单分支双分支课堂练习(1)

081_尚硅谷_单分支双分支课堂练习(1)1.单分支和双分支案例1 2.单分支和双分支案例2 3.单分支和双分支案例3 4.单分支和双分支案例4

C语言编程之旅:从入门到实战

第一节课:C 语言基础知识 第一个 C 程序Hello World 代码展示:#include <stdio.h> // 预处理指令,包含标准输入输出头文件int main() { // 主函数,程序入口printf("Hello, World!\n"); // 输出…

群晖NAS220+搭建Jupyter Notebook服务 - 何苦

群晖NAS220+搭建Jupyter Notebook服务网站:https://jupyter.org/Jupyter简介Jupyter Notebook(此前被称为 IPython notebook)是Jupyter项目中的一款产品,它是一个交互式笔记本,支持运行 40 多种编程语言。在Jupyt…

实用指南:大数据毕业设计 python智慧交通监控系统 Flask+Echarts可视化 百度地图 毕业设计(源码)✅

实用指南:大数据毕业设计 python智慧交通监控系统 Flask+Echarts可视化 百度地图 毕业设计(源码)✅pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: blo…

docling

doclinghttps://github.com/docling-project/docling/blob/main/docling/backend/msword_backend.pyhttps://www.zhihu.com/question/1961862463881451508/answer/1961873238784184663

Selenium元素定位总失败?这8种定位策略你必须掌握

作为一名自动化测试工程师,我们在使用Selenium进行Web自动化测试时,最常遇到也是最头疼的问题就是——元素定位失败。作为一名自动化测试工程师,我们在使用Selenium进行Web自动化测试时,最常遇到也是最头疼的问题就…

2025 年钢闸门厂家最新推荐排行榜:涵盖不锈钢 / 渠道 / 河道 / 水库 / 平面 / 手动 / 电动 / 液压钢闸门,聚焦十大实力厂家核心优势

引言在水利工程建设中,钢闸门的质量与性能直接决定工程安全稳定运行及水资源合理调控效果。当前钢闸门市场厂家众多,部分厂家存在生产设备落后、技术团队薄弱、产品质量不稳定,或仅重生产忽视售后安装与技术支持,亦…

2025 年最新铸铁闸门源头厂家推荐排行榜,涵盖四川 / 镶铜 / 渠道 / 圆形 / 方形等类型,助力一站式采购优质供应商

引言在水利工程建设中,铸铁闸门作为核心控制性设备,其质量、适配性与供货效率直接关系到工程进度与长期运行安全。当前市场上供应商数量繁杂,产品质量参差不齐,部分厂家存在规格不全、定制周期长、缺乏安装售后配套…

2025 年钢闸门源头厂家最新推荐口碑排行榜:聚焦防腐技术与密封性能,助力水利工程采购精准选型固定卷扬/四川卷扬/螺杆/螺杆式启闭机厂家推荐

水利工程与市政给排水项目的安全稳定运行,离不开钢闸门这一关键控制设备,其防腐技术与密封性能直接决定工程使用寿命与运维成本。当前市场中,部分钢闸门厂家为压缩成本,存在防腐涂层不达标、密封结构设计不合理等问…

2025 年耐火砖厂家最新推荐排行榜:绝热/轻质/莫来石等类型优质厂家权威榜单发布氧化铝泡沫/氧化铝空心球/抗渗碳/高温轻质莫来石耐火砖厂家推荐

引言 在陶瓷、冶金、石油、化工、新能源等工业领域,耐火砖是保障炉窑安全运行与延长使用寿命的核心基础材料。当前市场中,耐火砖品牌数量繁杂,产品质量差距显著,部分产品存在高温稳定性不足、导热率超标、抗热震性…