Testlink自动执行用例小程序
记得原来在一个公司时,具体很多原因,testlink上项目中的用例都需要执行形成漂亮的报告,但实际测试中又不需要去执行,所以就必须将用例根据上一次测试报告一个一个手工去贴结果刷用例,几百条用例,几天就浪费了,做完还什么都没获得。正好这二天没事,就用python写一个自动执行的小程序!~~~~~
思路:从测试计划及测试报告中提取caseID,及测试结果,使用webdriver去执行用例,使用yaml配置文件,将测试产品、测试计划、报告设成可配
需安装selenium、yaml组件
在TestLink 1.9.13上成功运行
代码是王道,直接上代码,如下:
#coding:utf-8
'''
Created on 2015-11-6
@author: Administrator
'''
from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time,random
import re,os
import urllib2
import yaml
print os.path.dirname(__file__) #获取当前文件绝对路径
try:
f=open('testlinkauto.yaml')
datadict=yaml.load(f)
testconfig=datadict['testlink']
except Exception,e:
print "The error is :",e start=time.clock()
chrome_driver_path=r'C:\\Program Files (x86)\Google\Chrome\Application\chromedriver.exe' #这里使用chrome,所以必需下载chromedriver驱动,否则无法执行
browser = webdriver.Chrome(chrome_driver_path)
print testconfig.get('address')
browser.get(testconfig.get('address')) #登陆
browser.find_element_by_id('login').clear()
browser.find_element_by_id('login').send_keys(testconfig.get('user'))
browser.find_element_by_name('tl_password').send_keys(testconfig.get('password'))
browser.find_element_by_name('login_submit').click()
time.sleep(2) #执行用例程序
def testCaseWrite(resultdict):
for case,result in resultdict.items():
print "%s The case is %s and result is %s" % (time.strftime('%Y-%m-%d %H:%M:%S'),case,result)
browser.switch_to_default_content() #切回默认的frame
browser.switch_to_frame('mainframe') #切到主frame
#切到左侧例表frame
browser.switch_to_frame('treeframe')
#选择要执行的用例
browser.find_element_by_name('filter_tc_id').clear()
browser.find_element_by_name('filter_tc_id').send_keys(case)
browser.find_element_by_id('doUpdateTree').click()
browser.find_element_by_id('expand_tree').click()
time.sleep(2)
#browser.find_elements_by_css_selector("//a[@href='javascrpit:ST(29,30)']").click()
#browser.find_element_by_xpath('//*[@id="ext-gen21"]/li/div/a').click()
#browser.find_element_by_xpath('//*[@id="ext-gen21"]/li/div/a').click()
browser.find_element_by_xpath("//a[contains(@href,'javascript:ST')]").click() #点击执行
time.sleep(5) #切换至右侧的用例frame
browser.switch_to_default_content()
browser.switch_to_frame('mainframe')
browser.switch_to_frame('workframe') #写执行记录并确定提交
#browser.find_element_by_class_name('step_note_textarea').send_keys(u'成功')
#browser.find_element_by_id('notes').send_keys(u'成功')
browser.find_element_by_xpath("//textarea[starts-with(@name,'notes')]").send_keys(result.decode('utf-8'))
time.sleep(2) #Select(browser.find_element_by_name('statusSingle')).select_by_value("p") #选择项目
Select(browser.find_element_by_xpath("//select[contains(@name,'statusSingle')]")).select_by_value("p")
#//*[@id="step_status_31"]
time.sleep(1)
browser.find_element_by_xpath("//input[contains(@name,'save_results')]").click()
time.sleep(random.uniform(2,4))#获取测试计划用例列表并去重排序
def getTestPlan(url):
date=urllib2.urlopen(url).read()
varpatten=testconfig['testprojectid']+'-\d{1,5}'
testlist=re.findall(varpatten,date)
aa=list(set(testlist))
aa.sort(key=lambda x:int(re.match('\D+-(\d+)',x).group(1))) #根据ID来排序
return aa #获取原来测试报告中用例及执行结果对应字典关系
def getTestResult(url):
date=urllib2.urlopen(url)
data=date.read()
global caselist
varpatten='测试用例 ('+testconfig['testprojectid']+'-\d+)'
print varpatten
caselist=re.findall(varpatten,data)
#caselist=re.findall('测试用例 (GX-\d+)',data)
resultlist=re.findall('执行备注.*?">(.*)</td',data)
return dict([(x,y) for x in caselist for y in resultlist ]) if __name__=='__main__':
#定位工具栏选项
browser.switch_to_frame('titlebar') #切换到iframe为titlebar上
print browser.current_url
#browser.find_element_by_name('testproject').click()
#遍历下拉框并选择需要的项目
select = browser.find_element_by_name("testproject")
allOptions = select.find_elements_by_tag_name("option") for option in allOptions:
print "Value is: " + option.get_attribute("value")
print "Text is:" +option.text
if testconfig['testprojectid'] in option.text:
option.click()
break time.sleep(5)
browser.find_element_by_xpath("//img[@title='执行']").click() #执行用例
browser.switch_to_default_content() #切回默认的frame
browser.switch_to_frame('mainframe') #切到主frame
print browser.current_url #执行程序
TestPlanCase=getTestPlan(testconfig['testplanurl'])
TestResultCase=getTestResult(testconfig['testreporturl'])
print TestResultCase #未有结果的列表并排序
print "计划中要执行的用例列表:" ,list(set(TestPlanCase))
print "原测试报告中已执行的用例列表:",list(set(caselist))
unuse=set(TestPlanCase)^set(caselist)
unuselist=list(unuse)
unuselist.sort(key=lambda x:int(re.match('\D+-(\d+)',x).group(1))) print "此次未执行的case列表为:",unuselist
print "总共%s个!" % len(unuselist)
print "大约要花费%d分钟" % (len(unuselist)*14/60) #执行
print TestResultCase
testCaseWrite(TestResultCase)
end=time.clock()
print "执行结束,总共花费%6.2f 秒时间" % (end-start) '''
#定位测试计划并选用
browser.switch_to_default_content()
browser.switch_to_frame('mainframe')
print browser.current_url
print testconfig['testplan']
browser.find_element_by_xpath("//div[contains(@class,'chosen-c')]/div/ul").click
#browser.find_element_by_xpath("//div[contains(@class,'chosen-c')]/div/ul/li[3]").click
#browser.find_element_by_xpath("//div[contains(@class,'chosen-c')]").click()
#WebDriverWait(browser,10).until(lambda the_driver: the_driver.find_element_by_tag_name('li').is_displayed())
#menu=browser.find_element_by_tag_name('li').find_element_by_link_text('GXVCP_IOS_D10V100_rc4')
#webdriver.ActionChains(browser).move_to_element(menu).perform()
#drop_down=browser.find_element_by_xpath("//div[contains(@class,'chosen-c')]/div/ul")
print drop_down
time.sleep(1)
#browser.find_element_by_link_text('GXVCP_IOS_D10V100_rc4') allOptions1 = drop_down.find_elements_by_tag_name("li")
print allOptions1
drop_down.find_element_by_link_text('GXVCP_IOS_D10V100_rc4')
browser.find_element_by_name('testplan')
Select(browser.find_element_by_name('testplan')).select_by_visible_text(testconfig['testplan']) '''
最后这个在定位测试计划时,一直定位不出来,所以还是得手工点击测试计划。 yaml配置文件内容:
testlink:
address: http://192.168.3.247:8080/testlink/login.php
user: xxxxx
password: 111111
testprojectid: GX
testplanurl: file:///F:/Private/testplan%20GXVCP_IOS_D10V100_rc3.htm
testreporturl: file:///F:/Private/testreport%20GXVCP_IOS_D10V100_rc4.htm
--更新,为了执行用例时间上不一致,使用random函数进行sleep,time.sleep(random.uniform(2,4))
测试计划定位方法已找到:详细见http://www.cnblogs.com/landhu/p/5010723.html
这里就不更新刷用例的程序了,有需要的朋友自行完善!
如使用有问题,请联系:
362299908@qq.com
Testlink自动执行用例小程序的更多相关文章
- Python小任务 - 如何编写指定时间执行的Python小程序
我们在平时的工作中经常会遇到这样的需求,需要再某个时间点执行一段程序逻辑. 那么,在python中我们是怎么做的呢? 下面看代码: waitDesignatedTimeToRun.py import ...
- 在Java中如何设置一个定时任务,在每天的一个时间点自动执行一个特定的程序
Quartz定时机制 首先导入jar包到程序内 quartz-all-1.6.0.jar 然后创建一个XML TimeConfig.xml 名字可以自己定义 <?xml version=&quo ...
- Asp.Net(C#)自动执行计划任务的程序实例分析
在业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称之为计划任务.实现计划任务的方法也有很多,可以采用SQ ...
- 零基础入门微信小程序开发
注:本文来源于:<零基础入门微信小程序开发> 课程介绍 本达人课是一个系列入门教程,目标是从 0 开始带领读者上手实战,课程以微信小程序的核心概念作为主线,介绍配置文件.页面样式文件.Ja ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
- [转]微信小程序、微信公众号、H5之间相互跳转
本文转自:https://www.cnblogs.com/colorful-paopao1/p/8608609.html 转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加 ...
- 微信小程序、微信公众号、H5之间相互跳转
转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息 ...
- 京东购物小程序 | Taro3 项目分包实践
背景 京东购物小程序作为京东小程序业务流量的主要入口,承载着许多的活动和页面,而很多的活动在小程序开展的同时,也会在京东 APP 端进行同步的 H5 端页面的投放.这时候,一个相同的活动,需要同时开发 ...
- 小程序跳转H5及其他页面
一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息等场景中. ...
随机推荐
- Objective-C语法之扩展(Extension)的使用
Objective-C 2.0增加了Class Extension用于解决两个问题: 可声明私有可读写的属性,而在类的声明中是同名的公开只读属性,从而来支持公开只读.私有可读写的属性 可声明私有方法: ...
- BarTender个别条码的前缀知识讲解
BarTender条码前缀可以强制其根据您选择的行业标准(如 GS1 或 AIM)向条形码的开头添加一个或多个字符.支持的符号体系仅包括2D-Pharmacode.Data Matri.GS1 Dat ...
- Two FIFOs of length 253 with 8-bits
FIFO 先入先出队列(First Input First Output,FIFO) 可以实现数据缓存. 一.FIFO的一些重要参数: 1.length:未知,待查 //补充:学长说:“FIFO一般只 ...
- ubuntu下安装程序的五种方法
在ubuntu当中,安装应用程序我所知道的有三种方法,分别是apt-get,dpkg安装deb和make install安装源码包三种.下面针对每一种方法各举例来说明. 一.apt-get方法 使用a ...
- python字符串 分片索引
字符串是字符的有序集合,可以通过其位置来获得具体的元素.在python中,字符串中的字符是通过索引来提取的,索引从0开始. python可以取负值,表示从末尾提取,最后一个为-1,倒数第二个为-2,即 ...
- 让Json更懂中文(JSON_UNESCAPED_UNICODE)
我们知道, 用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式, 还会在一定程度上增加传输的数据量. <?php echo json_ ...
- Apache双机热备
部署方案 1.1 方案设计 1.2 方案描述 如上图所示,我们要有三个可用的IP地址(切记不能与网络中其他机器IP重复),针对我使用的三个IP地址做如下说明: 10.16.252.10 //这个IP地 ...
- 升级MAC OX上的Python到3.4
第1步:下载Python3.4 下载地址如下: 下载Mac OS X 64-bit/32-bit installerhttps://www.python.org/downloads/release/p ...
- HBase--阿里未来发展
最近家里没网络,在公司加班写哈博客. HBase是一个开源的非关系型分布式数据库(NoSQL),基于谷歌的BigTable建模,是一个高可靠性.高性能.高伸缩的分布式存储系统,使用HBase技术可在廉 ...
- iOS开发-- 使用NSNumber将int、float、long等数据类型加入到数组或字典中
// 设置值 NSNumber *number=[NSNumber numberWithInt:45]; // 取值 NSLog(@"NSNumber %d",[number in ...