python+selenium自动化软件测试(第10章):测试驱动TDD
测试驱动开发模式,要求开发在写业务代码的时候,先写出测试代码,同时单元测试例子决定了如何来写产品的代码,并且不断的成功的执行编写的所有的单元测试例子,不断的完善单元测试例子进而完善产品代码, 这样随着功能的开发完成,测试代码也会对应的完成, 很显然,这是一个全新的开发模式, 在一定程度上,可以完全的提高软件的质量,以及开发可以对自己写的代码进行一个全面的评估和测试。
TDD 模式是一个很大的概念,在这里, 我重点介绍下测试驱动模式与自动化的融合以及精简自动化的测试代码。
下面我们来看一个登录的案例:
coding:utf-8
import unittest
from selenium import webdriver class developTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.driver.maximize_window()
self.driver.get('http://xxxx/login')
self.addCleanup(self.driver.quit) def testLogin(self):
#用户名输入
name = self.driver.find_element_by_id('xxxx')
name.clean()
name.send_keys('xxxx') #密码输入
passwd = self.driver.find_element_by_id('xxxx')
passwd.clear()
passwd.send_keys('xxxx') #点击登录
self.driver.find_element_by_id('xxxx').click() #获取到用户昵称
userName = self.driver.find_element_by_xpath("xxx")
userlnfo = userName.text #退出系统
userName.click()
self.driver.find_element_by_xpath("xxxx").click()
self.assentTrue(userlnfo in 'linux') if __name__ =='__main__':
unittest.main(verbosity=2)
如上的代码, 我们成功的实现了登录 ,获取到用户的昵称,退出系统,以及验证用户昵称这样的一个过程, 但是问题也就来了,如果我登录系统 N 次以及退出系统次,那么就意味着写登录退出就得 N次,很明显,这样很多的登录退出的代码都是一致的,增加了工作量,如下, 我通过把登录,退出,获取到用户昵称,写成一个单独的函数,然后使用到了直接调用对应的函数(调用的时候记得导入), 文件名称是 kuihua.py, 具体代码为如下:
#coding:utf-8
#登录函数 def login(driver,usenname='I59xxxxx',password='server'):
driver.find_element_by_id('xxxx').send_keys(usenname)
driver.find_element_by_id('xxxx').send_keys(password)
driver.find_element_by_id('xxxx').click() #获取用户昵称
def getName(driver):
return driver.find_element_by_xpath("xxxx").text #退出系统
def exitSystem(driver): dniver.find_element_by_xpath("xxxx").click()
dniver.find_element_by_xpath("xxxx").click() 如上函数之后,测试脚本就精简很多了,测试脚本见如下: #coding:utf-8
import unittest
from selenium import webdriver
import kuihua class developTest(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Firefox()
self.driver.implicitly_wait(30)
self.driver.maximize_window()
self.driver.get('http://my.weke.com/login.html')
self.addCleanup(self.driver.quit) def testLogin(self):
kuihua.login(self.driver)
userInfo=vke.getName(self.driver)
vke.exitSystem(self.driver)
self.assentTrue(usenInfo in 'linux') if __name == '__main__':
unittest.main(verbosity=2)
通过这样的一个实例, 我们把测试脚本精简了很多,其实还可以把最后一步精简下,但是我一般感觉,最后一步还是在测试代码中比较好,因此我们可以总结出如下几点:
1、 对于某些公用的功能,如登录,退出,单独写成一个函数, 需要
的时候,直接调用函数;
2、 验证点一定要写在最后一步,本实例验证用户昵称部分,不可以写在退出之前验证,先获取到用户昵称,退出系统,再验证用户昵称
3、 尽量保持测试脚本与页面对象元素分离开,这样即使系统需求变更或者开发把页面元素更改了,我们只在一个地方维护,而不影响 tescase 的脚本。虽然我们实现了把测试用例的代码精简化, 实现了测试脚本与页面对象的分离,实现了后期维护页面对象只在一个地方维护,但是还是存在很多的缺点, 我们可不可以把使用到的数据,页面对象放在.csv.xml 文件中了?答案当然是可以, 下来部分我们重点介绍把使用到的数据放在.txt, .csv, . xlsx, xml 文件中, 同时介绍 ddt 模块的安装以及使用方法, 来继续重构我们的测试代码。
10.1 ddt 模块
ddt 是 python 的第三库, 全名称为: Data-Driven/Decorated Tests。ddt 模块提供了创建数据驱动的测试,关于该模块,建议到官方查看详细的说明, 安装方法分别为命令行安装或者下载文件进行安装,分别进行说明,二种安装的方式具体见如下:
1、下载ddt文件,让后解压,到解压的目录下,输入: pythonsetup.py install 安装,见如下的截图:
2、 直接使用 pip 在线安装 ddt, 命令为: pip install ddt
在实际自动化测试中的应用,代码如下:
#coding:utf-8 import unittest
from selenium import webdriver
from ddt import ddt,data,unpack
from time import sleep @ddt
class developTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.addcleanup(self.driver.quit)@data(('','',u'手机/邮箱/用户名'),('admin','',u'请您填写密码'),('admin','admin',u'您输入的帐号或密码有误,忘记密码?')) @unpack
def testLogin(self, sendValue1, sendValue2, expected):
self.driver.find_element_by_link_text(u'登录’).click()
sleep(2)
#输入百度账号
userName=self.driver.find_element_by_id('xxxx')
userName.clear()
userMame.send_keys(sendValuel) #输入百度密码
password=self.driver.find_element_by_id('xxxxx')
password.clear()
password.send_keys(sendValue2) #点击登录按钮
self.driver.find_element_by_id('xxxxx').click()
#获取到返回的错误信息
errorText=self.driver.find_element_by_xpath("xxxxx").text
self.assentTrue(emonText, expected) if __name__ =='__main__':
unittest.main(verbosity=2)
从如上的代码以及执行结果的截图,我们可以地得到,这个测试用例
验证了三个验证点, 分别是:
1、 百度账号为空, 密码为空, 点击登录按钮, 验证返回的错误信息
2、 输入百度账号,未输入密码, 验证返回的错误信息
3、 输入错误的账号和错误的密码, 验证返回的错误信息
但是我们的核心代码只有如下的几行:
ddt 模块的优秀之处, 几行代码,实现多个测试点, 可以少写了很多代码。
10.2 csv 文件的处理
python提供了对 csv文件处理的模块,直接 import csv就可以了,那么神秘是 csv 文件了? csv 文件全名称为 Comma-SeparatedValues,csv 是通用的,相对简单的文件格式,其文件已纯文件形式存储数据。 我们把数据存储在 csv 的文件中,然后写一个函数获取到 csv文件的数据, 在自动化中引用,这样,我们自动化中使用到的数据,就可以直接在 csv 文件中维护了,见下面的一个 csv 文件的格式:
下面我们实现读写 csv 文件中的数据,具体见如下实现的代码:
为了具体读取到 csv 文件中某一列的数据,我们可以把读取 csv 文件的方法修改如下,见代码:
如我们需要读取第一个 selenium, csv 文件内容见如上的截图,那么调用的方法代码为:
执行后如下截图:
已百度搜索输入框为实例,在搜索输入框输入 csv 文件中的字符,我们把读写 csv 文件的函数写在 location.py 的模块中,见 location.py的源码:
#coding:utf-8
import csv
#读取CSV的文件
def getCsv(valuel,value2,file_name='d:/test.csv'):
nows=[]
with open(file_name,'nb') as f:
neaders=csv.reader(f,delimiters't ',quotechar='|')
next(readers^None) for row in readers:
rows.append(row)
return rows[valuel][value2] #csv文件中写数据
def writeCsv(file_name='d:/test.csv'):
with open(file_name,'wb') as f:
wnite=csv.writer(f)
write.writerow(['Element','system'])data=[
('selenium''webdriver'),
('appium','android'),
('appium','ios'),
('selenium','python')] write.writerows(data)
f.close()
把测试代码写在 baiduTest.py 的模块中,见该模块的源码:
#coding:utf-8 from selenium import webdriver
import location
import unittest
import time
time.sleep(5) class BaiduTest(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.implicitly一wait(30)
self.driver.get(location.getCsv(4,0)) def testCase_01(self):
'''获取CSV文件中第二列第_位的数据进行搜索'''
self.driver.find_element_by_id('kw').send_keys(location.getCsv(l,0)) def tearDown(self):
self.driver.quit() if __name__=='__main__':
suite = unittest.TestLoader().loadTestsFnomTestCase(BaiduTest)
unittest.TextTestRunner(verbosity=2).run(suite)
在如上的测试代码中,我把 url,以及搜索的字符都放在了 csv 的文件中,在测试脚本中,只需要调用读取 csv 文件的函数,这样,我们就可以实现了把测试使用到的数据存储在 csv 的文件中,来进行处理。
在前面我这边介绍到了 ddt 的模块,那么现在我这边 ddt 模块和csv 文件结合,来进行自动化的测试,编辑后的 csv 文件后:
我重新写 location.py 的模块,具体见该模块的源码:
#coding:utf-8 import csv def getCsv(file_name):
rows=[]
with open(file_name, 'rb') as f:
readers = csv.reader(f, delimiter=',', quotechar='|')
next(readers, None) for row in readers:
rows.append(row)
return rows
实现在百度搜索输入框输入搜索关键字分别是 selenium,appium,那么实现的测试模块 baiduTest.py 的源码为:
#coding:utf-8 from selenium import webdriver
from ddt import ddt,data,unpack
import location
import time import unittest, sys
neload(sys)
sys.setdefaultencoding('utf-8') @ddt
class BaiduTest(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Firefox()self.driver.maximize_window()
self.driver.implicitly_wait(30)
self.driver.get('http://www.baidu.com/')
@data(*location.getCsv("d:\\xxx.csv")) @unpack
def testCase_01(self,actual,expect):
'''ddt模块与csv文件结合的使用'''
self.driver.find_element_by_id('kw').send_keys(actual) time.sleep(5) def tearDown(self):
self.driver.quit() if '__name__' == '__main__':
suite=unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
unittest.TextTestRunner(verbosity=2).run(suite)
我们就实现了单独读取 csv 文件中的内容,或者 csv 文件和 ddt模块结合来在自动化中使用。
10.3 xlsx 文件的处理
一般性的,数据存储在 excel 中,也是一种选择,但是必须安装对应的库,要不 python 是无法操作 excel 文件的,安装的第三方库为为 xlrd, 安装命令为:
pip install xlrd
安装过程:
Excel 文件的后缀格式为.xlsx,实例中 excel 的数据为:
所以,我们需要读取 excel 中的数据,首先需要 import xlrd,然后才可以读取 excel 文件中的数据。 在 excel 文件中, cell 是单元格,sheet 是工作表,一个工作表由 N 个单元格来组成。下面来实现读取
excel 文件中的数据,见如下的代码:
我把读取 excel 中的数据写成一个函数, 先导入 xlrd 的库,然后创建book,以及获取 sheet 对象,依次获取 sheet 对象中的数据,在如上的excel 数据中,如果我想获取“请你填写密码”,那么直接调用该函数,并且传对应的参数分别为(0,1),见执行的代码截图:
如果读取 excel 一个 sheet 对象的所有数据,修改后的代码为:
我们已百度登录为实例,来说明 excel 文件在自动化中的引用,
测试点分别为:
1、输入百度账号,未输入百度密码,点击登陆,验证返回的错误信息;
2、输入错误的百度账号密码,点击登录,验证返回的错误信息;
我们读 excel文件的函数,登录百度的函数写在 location.py的模块中,见 location.py 模块的代码:
#coding:utf-8 import csv, xlrd
from selenium import Webdriver
import time as t def getCsv(file_name):
nows = []
with open(file_name,’rb') as f:
readers = csv.reader(f,delimiters = ',',quotechar = '|')
next(readers,None)
for row in readers:
rows.append(row)
return rows def getExcel(nowValue, colValue, file_name = 'd:\\xxx.xlsx'):
'''
:param rowValue:表格的行
:param colValue:表格的列
:panam file_name: excel 文件
:return:
'''
book = xlrd.open_workbook(file_name)
sheet = book.sheet_by_index(0)return sheet.cell_value(rowValue,colValue) def clickButton(driver):
driver.find_element_by_xpath("xxx").click()
t.sleep(2) def clickLogin(driver, username, password):
name = driver.find_element_by_id('xxx')
name.clear()
name.send_keys(usenname)
t.sleep(2) passwd=driver.find_element_by_id('xxxx')
passwd.clear()
passwd.send_keys(password)
t.sleep(2) driver.find_element_by_id('xxx').click()
t.sleep(2) #获取返回的错误信息
def getText(driver):
return
driver.find_element_by_xpath("xxx").text
把测试代码写在 baiduTest.py 的模块中,见该模块的测试代码:
#coding:utf-8 from selenium import webdriver
import time as t
import location
import unittest, sys
reload(sys) sys.setdefaultencoding('utf-8') class BaiduTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.maximize_window()
self.driver.implicitly一wait(30)
self.driver.get('http://www.xxx.com/')
def testCase_01(self):
'''
验证只输入百度账号密码,点击登录返回的错误信息
:return:
'''
driver = self.driver
location.clickButton(driver)
location.clickLogin(driver, location.getExcel(0,0), location.getExcel(l,0))
self.assentEqual(location.getText(driver, location.getExcel(l,l)) def testCase_02(self):
'''
验证只输入百度账号,未输入密码,点击登录返回的错误信息
:return:
'''
driver = self.driver
location.clickButton(driver)
location.clickLogin(driver, location.getExcel(0,0),location.getExcel(2,0))
self.assentEqual(location.getText(driver, location.getExcel(0,l)) def tearDown(self):
self.driver.quit() if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
unittest.TextTestRunner(verbosity=2).run(suite)
这样,我们就实现了把测试中使用到的数据,存储在 excel 中,然后利用 xlrd 模块来读取 excel 中的数据,达到测试代码与数据的分离。
详细的介绍了 ddt 模块的安装以及在自动化项目中的使用,我们再已验证 V 客网登录界面为实例,来说明 ddt 模块在自动化中的实战,验证点分别为如下几点:
验证点一:输入无效的用户名和密码,验证返回的错误信息
验证点二:输入有效的用户名和无效的密码,验证返回的错误信息
验证点三:输入无效的邮箱和无效的密码,验证返回的错误信息
我们把读取数据的方法,登录以及获取错误信息,编写的 location.py的模块中,见 location.py 的源码:
python+selenium自动化软件测试(第10章):测试驱动TDD的更多相关文章
- python+selenium自动化软件测试(第13章):selenium面试题
前言最近看到群里有小伙伴贴出一组面试题,最近又是跳槽黄金季节,小编忍不住抽出一点时间总结了下 一.selenium中如何判断元素是否存在?expected_conditions模块提供了16种判断方法 ...
- python+selenium自动化软件测试(第8章) :多线程
前戏:线程的基础 运行多个线程同时运行几个不同的程序类似,但具有以下优点:进程内共享多线程与主线程相同的数据空间,如果他们是独立的进程,可以共享信息或互相沟通更容易.线程有时称为轻量级进程,他们并不需 ...
- python+selenium自动化软件测试(第9章) :Logging模块
9.1 Logging模块 什么是日志记录?记录是跟踪运行时发生的事件的一种手段.该软件的开发人员将记录调用添加到其代码中,以指示某些事件已发生.事件由描述性消息描述,该消息可以可选地包含可变数据(即 ...
- python+selenium自动化软件测试(第7章):Page Object模式
什么是Page ObjectModel模式Page Objects是selenium的一种测试设计模式,主要将每个页面看作是一个class.class的内容主要包括属性和方法,属性不难理解,就是这个页 ...
- python+selenium自动化软件测试(第16章):基础实战(3)
#coding:utf-8 from time import sleep from selenium import webdriver class cloudedge_register(object) ...
- python+selenium自动化软件测试(第15章):基础实战(2)
#coding:utf-8 #for windows/py2.7 from time import sleep from selenium import webdriver browser = web ...
- python+selenium自动化软件测试(第14章):基础实战(1)
#coding=utf- from selenium import webdriven from selenium.webdriver.common.by import By from seleniu ...
- python+selenium自动化软件测试(第11章):持续集成jenkins和GitHub的使用
11.1 jenkins持续集成环境 相关安装包下载链接:http://pan.baidu.com/s/1qYhmlg4 密码:dcw2赠送jenkins集成selenium环境视频链接http:// ...
- python+selenium自动化软件测试(第6章):selenium phantomjs页面解析使用
我们都知道Selenium是一个Web的自动化测试工具,可以在多平台下操作多种浏览器进行各种动作,比如运行浏览器,访问页面,点击按钮,提交表单,浏览器窗口调整,鼠标右键和拖放动作,下拉框和对话框处理等 ...
随机推荐
- mybaits错误解决:There is no getter for property named 'parentId ' in class 'java.lang.String'
在使用mybaitis传参数的时候,如果仅传入一个类型为String的参数,那么在 xml文件中应该使用_parameter来代替参数名. 比如mapper中如下方法,只有一个String值 publ ...
- iOS开发实战-时光记账Demo 本地数据库版
现在记账APP也是用途比较广泛 自己写了个简单的demo 欢迎指正 效果 分析 1.思维推导 首先简单的做了下思维推导 2.文件结构 大致框架想好后就可以着手开始准备了 数据库管理:coreData ...
- java中方法的参数传递机制
问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参数.当一个对象实例作为一个 ...
- Chrome调试工具developer tool技巧
Chrome这个浏览器赞的不能再赞了,给前端的开发调试工作带来了极大的效率提升. Chrome的简洁.快速吸引了无数人,它的启动速度.页面解析速度都很快,同时得益于Google V8的快速,Javas ...
- codeforces 475D. CGCDSSQ
D. CGCDSSQ time limit per test 2 seconds memory limit per test 256 megabytes Given a sequence of int ...
- 24. leetcode 409. Longest Palindrome
409. Longest Palindrome Given a string which consists of lowercase or uppercase letters, find the le ...
- windows本地提权对照表(转载)
2003 systeminfo>C:\Windows\Temp\temp.txt&(for %i in (KB3057191 KB2840221 KB3000061 KB2850 ...
- 华为软件开发云CloudIDE功能简测
华为软件开发云CloudIDE是面向软件开发者的云端开发环境,支持在线编写代码,智能提示,代码提交,代码片段智能搜索等功能. CloudIDE实现了大部分IDE的功能,同时克服了全能IDE的缺点. 一 ...
- Web安全测试——威胁攻防
SQL注入 部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患.用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL In ...
- Jmeter==HTTP信息头管理器的作用
HTTP信息头管理器在Jmeter的使用过程中起着很重要的作用,通常我们在通过Jmeter向服务器发送http请求(get或者post)的时候,往往后端需要一些验证信息,比如说web服务器需要带过去c ...