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及其他页面
一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息等场景中. ...
随机推荐
- Win7 共享打印机 “错误:共享无法保存设置”
原因:windows的后台防火墙服务进程[Windows Firewall{服务描述}.MpsSvc{服务名字}] 关闭了.services.smc 关闭 解决:重启服务 关闭防火墙的功能,通过控制面 ...
- SDK Manager.exe和AVD Manager.exe缺失,Android SDK Tools在检查java环境时卡住了,未响应卡死!
之前安装Android Studio的时候根据提示安装了Android SDK,但是发现目录下没有SDK Manager.exe和AVD Manager.exe,导致SDK的一些操作很不方便! 不知道 ...
- python中,如何将两个变量值进行拼接
说明: 字符串和字符串之间可以拼接,那么变量和变量之间如何进行拼接,在此记录下. 操作过程: 1.通过加号 + 操作符,将两个变量拼接在一起 >>> prefix = 'p' > ...
- 如何在 CentOS 7 上安装 Docker
Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单.容器就像是轻量级的虚拟机,并且可以以毫秒级的速度来启动或停止.Docker 帮助系统管理员和程序员在容器中开发应用程序,并且 ...
- AES五种加密模式
分组密码在加密时明文分组的长度是固定的,而实用中待加密消息的数据量是不定的,数据格式可能是多种多样的.为了能在各种应用场合安全地使用分组密码,通常对不同的使用目的运用不同的工作模式. 一.电码本模式( ...
- Nginx配置中文域名
今天碰到一个好玩的问题,还以为是nginx的缓存,各种清理就差把nginx卸载了,后来想想不对应该是中文域名的问题,对中文进行编码,搞定,如下: ... server { listen 80; ser ...
- Windows系统下运行某些程序时缺少“Msflxgrd.ocx”的解决方法
出现这样的错误就是系统缺少相应的库文件,我们安装即可. 下载Msflxgrd.ocx,这里提供一个下载网址:https://www.ocxme.com/files/msflxgrd_ocx 64位系统 ...
- Java - Calendar类的使用
今天在写代码时需要用到时间相关的类,一开始,数据库中存的数据类型是timestamp的,所以在Java中就使用了 Timestamp类型,但当调用Timestamp类型的方法时发现,它的很多方法都是d ...
- 使用tinyproxy搭建http代理
一.前言 二.搭建环境 * Linux laptop 2.6.32-45-generic #100-Ubuntu SMP Wed Nov 14 10:41:11 UTC 2012 i686 GNU ...
- VS2015编译提示无法运行“rc.exe”
使用VSx64命令行编译项目,提示无法运行“rc.exe” 想办法搜索rc.exe和rcdll.dll这两个文件,然后拷贝到C:\Program Files (x86)\Microsoft Visua ...