R语言 Testlink excel 转XML 批量导入测试用例

Testlink作为一个开源的项目管理工具,功能是非常强大的。不得不说,在测试用例创建方面功能有些弱。
大家都习惯了在excel中写测试用例,当要导入到Testlink中时需要一个一个的创建。
这耗费了大量的时间,在网络不好的情况下还容易出现了延迟,降低了效率。
幸好Testlink提供了XML批量导入测试用例方式,但只支持XML格式,所以这就需要我们把excel转换成XML格式的文件。

首先看一下excel中的测试用例格式

image.png

由于时间原因,只用到了用例编号 测试用例名字 前提条件 测试步骤 其他均用统一给定值,然后写死在XML中

在R中导入excel提取数据

#################提取步骤###################
steplist<-vector("list",1)
resultlist<-vector("list",1)
x<-0
y<-1
for(i in 1:length(ceshiyongli$用例编号))
{
  if(is.na(ceshiyongli$用例编号[i]))
  {
  
  }
  else
  {
    x=x+1
    steplist[[x]]<-x
    resultlist[[x]]<-x
  }
}
x<-0
y<-1
for(i in 1:length(ceshiyongli$用例编号))
{
  if(is.na(ceshiyongli$用例编号[i]))
  {
    y=y+1
  steplist[[x]][y]<-ceshiyongli$测试步骤[i]
  resultlist[[x]][y]<-ceshiyongli$预期结果[i]
  }
  else
  {
    y<-1
    x=x+1
    steplist[[x]][y]<-ceshiyongli$测试步骤[i]
    resultlist[[x]][y]<-ceshiyongli$预期结果[i]
  }
}
##############################提取用例标识#################
x<-0
yongliname<-c()
for(i in 1:length(ceshiyongli$用例编号))
{
  if(is.na(ceshiyongli$用例编号[i]))
  {
    
  }
  else
  {
    x=x+1
    yongliname[x]<-ceshiyongli$测试用例名称[i]
  }
}
#############################node_order##########################
x<-0
node_order<-c()
for(i in 1:length(ceshiyongli$用例编号))
{
  if(is.na(ceshiyongli$用例编号[i]))
  {
    
  }
  else
  {
    x=x+1
    node_order[x]<-x
  }
}
#######################externalid##################
x<-0
externalid<-c()
for(i in 1:length(ceshiyongli$用例编号))
{
  if(is.na(ceshiyongli$用例编号[i]))
  {
    
  }
  else
  {
    x=x+1
    externalid[x]<-x
  }
}

############################fullexternalid#####################
x<-0
fullexternalid<-c()
for(i in 1:length(ceshiyongli$用例编号))
{
  if(is.na(ceshiyongli$用例编号[i]))
  {
    
  }
  else
  {
    x=x+1
    fullexternalid[x]<-paste0("TS-",x)
  }
}

########################

用XML包来创建XML文件并赋值

########创建测试用例集####################
n2<-xmlNode("testsuite",attrs = c("id"="15",name="类型管理"))
n2<-append.xmlNode(n2,xmlNode("node_order","<![CDATA[1]]>"))
n2<-append.xmlNode(n2,xmlNode("details","<![CDATA[<p>类型管理</p>]]>"))
################################
##########对从excel中提取的数据进行创建测试用例,并加入到测试用例集中#####################

##########这里用了一个比较笨的方法来对步骤进行判断,有好的方法欢迎评论##########
for(i in 1:length(yongliname))
{
  if(length(steplist[[i]])==1)
  {
  sr<-stepf(steplist[[i]][1],"","","","",resultlist[[i]][1],"","","","")
  n3<-testxml(i,yongliname[i],i,externalid[i],fullexternalid[i],sr[1],sr[2],sr[3],sr[4],sr[5],sr[6],sr[7],sr[8],sr[9],sr[10])
  }
  else if(length(steplist[[i]])==2)
  {
    sr<-stepf(steplist[[i]][1],steplist[[i]][2],"","","",resultlist[[i]][1],resultlist[[i]][2],"","","")
    n3<-testxml(i,yongliname[i],i,externalid[i],fullexternalid[i],sr[1],sr[2],sr[3],sr[4],sr[5],sr[6],sr[7],sr[8],sr[9],sr[10])
  }
  else if(length(steplist[[i]])==3)
  {
    sr<-stepf(steplist[[i]][1],steplist[[i]][2],steplist[[i]][3],"","",resultlist[[i]][1],resultlist[[i]][2],resultlist[[i]][3],"","")
    n3<-testxml(i,yongliname[i],i,externalid[i],fullexternalid[i],sr[1],sr[2],sr[3],sr[4],sr[5],sr[6],sr[7],sr[8],sr[9],sr[10])
  }
  else if(length(steplist[[i]])==4)
  {
    sr<-stepf(steplist[[i]][1],steplist[[i]][2],steplist[[i]][3],steplist[[i]][4],"",resultlist[[i]][1],resultlist[[i]][2],resultlist[[i]][3],resultlist[[i]][4],"")
    n3<-testxml(i,yongliname[i],i,externalid[i],fullexternalid[i],sr[1],sr[2],sr[3],sr[4],sr[5],sr[6],sr[7],sr[8],sr[9],sr[10])
  }
  else
  {
    sr<-stepf(steplist[[i]][1],steplist[[i]][2],steplist[[i]][3],steplist[[i]][4],steplist[[i]][5],resultlist[[i]][1],resultlist[[i]][2],resultlist[[i]][3],resultlist[[i]][4],resultlist[[i]][5])
    n3<-testxml(i,yongliname[i],i,externalid[i],fullexternalid[i],sr[1],sr[2],sr[3],sr[4],sr[5],sr[6],sr[7],sr[8],sr[9],sr[10])
  }
########将测试用例加入到测试用例集中##############
  n2<-append.xmlNode(n2,n3)
  print(i)
  
}
step5<-vector("list",5)
result<-vector("list",5)
#############创建步骤和期望结果函数,默认5个###########
stepf<-function(s1,s2,s3,s4,s5,r1,r2,r3,r4,r5)
{
step1<-paste0("<![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:223px'><tbody><tr><td>",s1,"</td></tr></tbody></table>]]>")
result1<-paste0("   <![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:194px'><tbody><tr><td>",r1,"</td></tr></tbody></table>]]>")
step2<-paste0("<![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:223px'><tbody><tr><td>",s2,"</td></tr></tbody></table>]]>")
result2<-paste0("   <![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:194px'><tbody><tr><td>",r2,"</td></tr></tbody></table>]]>")
step3<-paste0("<![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:223px'><tbody><tr><td>",s3,"</td></tr></tbody></table>]]>")
result3<-paste0("   <![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:194px'><tbody><tr><td>",r3,"</td></tr></tbody></table>]]>")
step4<-paste0("<![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:223px'><tbody><tr><td>",s4,"</td></tr></tbody></table>]]>")
result4<-paste0("   <![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:194px'><tbody><tr><td>",r4,"</td></tr></tbody></table>]]>")
step5<-paste0("<![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:223px'><tbody><tr><td>",s5,"</td></tr></tbody></table>]]>")
result5<-paste0("   <![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:194px'><tbody><tr><td>",r5,"</td></tr></tbody></table>]]>")
return(c(step1,step2,step3,step4,step5,result1,result2,result3,result4,result5))
}

########创建测试用例函数,默认5个步骤,由于时间问题,细节方面没有做处理###############################
testxml<-function(internalid,name1,node_order1,externalid1,fullexternalid1,step_1,step_2,step_3,step_4,step_5,result_1,result_2,result_3,result_4,result_5)
{
n1<-xmlNode("testcase",attrs = c("internalid"=internalid,name=name1))
n1<-append.xmlNode(n1,xmlNode("node_order",paste0("<![CDATA[",node_order1,"]]>")))
n1<-append.xmlNode(n1,xmlNode("externalid",paste0("<![CDATA[",externalid1,"]]>")))
n1<-append.xmlNode(n1,xmlNode("fullexternalid",paste0("<![CDATA[",fullexternalid1,"]]>")))
n1<-append.xmlNode(n1,xmlNode("version","<![CDATA[1]]>"))
n1<-append.xmlNode(n1,xmlNode("summary","<![CDATA[<p></p>]]>"))
n1<-append.xmlNode(n1,xmlNode("preconditions","<![CDATA[<table border='0' cellpadding='0' cellspacing='0' style='width:188px'><tbody><tr><td>1.Tinyshop部署成功2.Tinyshopn能正常运行</td></tr></tbody></table>]]>"))
n1<-append.xmlNode(n1,xmlNode("execution_type","<![CDATA[1]]>"))
n1<-append.xmlNode(n1,xmlNode("importance","<![CDATA[2]]>"))
n1<-append.xmlNode(n1,xmlNode("estimated_exec_duration","1.00"))
n1<-append.xmlNode(n1,xmlNode("status","7"))
n1<-append.xmlNode(n1,xmlNode("is_open","1"))
n1<-append.xmlNode(n1,xmlNode("active","1"))
n1<-append.xmlNode(n1,xmlNode("steps",xmlNode("step",
                                              xmlNode("step_number","<![CDATA[1]]>"),
                                              xmlNode("actions",step_1),
                                              xmlNode("expectedresults",result_1),
                                              xmlNode("execution_type","<![CDATA[1]]>")
                                              ),
                                      xmlNode("step",
                                      xmlNode("step_number","<![CDATA[2]]>"),
                                      xmlNode("actions",step_2),
                                      xmlNode("expectedresults",result_2),
                                      xmlNode("execution_type","<![CDATA[1]]>")
                              ),
                              xmlNode("step",
                                      xmlNode("step_number","<![CDATA[3]]>"),
                                      xmlNode("actions",step_3),
                                      xmlNode("expectedresults",result_3),
                                      xmlNode("execution_type","<![CDATA[1]]>")
                              ),
                              xmlNode("step",
                                      xmlNode("step_number","<![CDATA[4]]>"),
                                      xmlNode("actions",step_4),
                                      xmlNode("expectedresults",result_4),
                                      xmlNode("execution_type","<![CDATA[1]]>")
                              ),
                              xmlNode("step",
                                      xmlNode("step_number","<![CDATA[5]]>"),
                                      xmlNode("actions",step_5),
                                      xmlNode("expectedresults",result_5),
                                      xmlNode("execution_type","<![CDATA[1]]>")
                              )
                              ))
return(n1)
}

导出为XML

saveXML(n2, file="out.xml",encoding="UTF-8")

这里有一个小缺陷没有继续优化,但不影响使用

由于XML生成时的编码问题,元素值中出现<会被替换成(<) >替换成(>) '被替换成(')
在Notepad++里查找替换下就行


image.png
image.png

image.png

这样就可把替换完成的XML直接导入到Testlink中了

如果导入时出现警告:xml_load_ko
可能是R语言默认的编码问题,和本地主机编码不匹配。
解决方法是:在本地创建一个文本,把XML文件内容复制进去,再把后缀名改成xml即可

最后,谨以此文献给努力拼搏的测试同学们!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容