一,线性测试
1.概念:
通过录制或编写对应应用程序的操作步骤产生的线性脚本。单纯的来模拟用户完整的操作场景。
(操作,重复操作,数据)都混合在一起。
2.优点:
每个脚本相对独立,且不产生其他依赖和调用。
3.缺点:
开发成本高,用例之间存在重复的操作。比如重复的用户登录和退出。
维护成本高,由于重复的操作,当重复的操作发生改变时,则需要逐一进行脚本的修改。
4.线性测试实例
用户登录
以下的用户名密码到时候自己去申请,就不将笔者的用户密码贴出来了。
# coding=utf-8 ''' Created on 2016-7-20 @author: Jennifer Project:简单元素操作登录126邮箱,元素的clear(),send_keys(),click()操作 在定位的时候发现有些元素定位不到,最后发现有iframe,frame中实际上是嵌入了另一个页面。 如果iframe有name或id的话,直接使用switch_to_frame("name值")或switch_to_frame("id值"), 这是最理想的方法,也是最简单好用的方法。 ''' from selenium import webdriver import time driver=webdriver.Firefox() driver.get(r'http://www.126.com/') #字符串加r,防止转义。 time.sleep(3) print '开始登录邮箱' try: assert '126' in driver.title #title是变量,不能title() except AssertionError: print "error:网址输入不正确" else: print "记录日志:网址输入正确" # driver.switch_to_frame('x-URS-iframe') #跳转到iframe框架 driver.switch_to.frame('x-URS-iframe') #同上面语句一样,跳转到iframe框架 username=driver.find_element_by_name('email') username.clear() username.send_keys('Jennifer···') time.sleep(0.1) userpasswd=driver.find_element_by_name('password') userpasswd.clear() userpasswd.send_keys('·····') time.sleep(0.1) loginbt=driver.find_element_by_id('dologin') loginbt.click() time.sleep(3) try: assert '网易邮箱' in driver.title except AssertionError: print '邮箱登录失败' else: print '邮箱登录成功' finally: #操作:收信,写信等操作,暂不写例子了 driver.quit() print '测试结束'
二,模块化驱动测试
1.概念:
将重复的操作独立成功共模块,当用例执行过程中需要用到这一模块操作时则被调用。
操作+(重复操作,数据)混合在一起。
2.优点:
由于最大限度消除了重复,从而提高了开发效率和提高测试用例的可维护性。
3.缺点:
虽然模块化的步骤相同,但是测试数据不同。比如说重复的登录模块,如果登录用户不同,依旧要重复编写登录脚本。
4.实例
公共模块:对登陆和退出进行模块化封装
以下的用户名密码到时候自己去申请,就不将笔者的用户密码贴出来了。
# coding=utf-8 ''' Created on 2016-7-27 @author: Jennifer Project:模块化驱动测试实例,将重复的登录脚本放在单独的脚本中供其他用例调用 ''' import time class Login(): def user_login(self,driver): username=driver.find_element_by_name('email') username.clear() username.send_keys('username') time.sleep(0.1) userpasswd=driver.find_element_by_name('password') userpasswd.clear() userpasswd.send_keys('password') time.sleep(0.1) loginbt=driver.find_element_by_id('dologin') loginbt.click() time.sleep(3) def user_logout(self,driver): driver.find_element_by_link_text(u'退出').click() driver.quit()
写信用例:以下代码用了各种定位方法,值得学习,后续再重新对这部分进行总结
直接调用模块的登录和退出方法。
# coding=utf-8 ''' Created on 2016-7-27 @author: Jennifer Project:发送邮件 ''' from selenium import webdriver import time from test_5_2_public import Login #由于公共模块文件命名为test_5_2_public driver=webdriver.Firefox() driver.implicitly_wait(30) driver.get(r'http://www.126.com/') #字符串加r,防止转义。 time.sleep(3) driver.switch_to.frame('x-URS-iframe') #调用登录模块 Login().user_login(driver) time.sleep(10) #发送邮件 #点击发件箱 #_mail_component_61_61是动态id,所以不能用于定位 #driver.find_element_by_css_selector('#_mail_component_61_61>span.oz0').click() #不能加u"//span[contains(text(),u'写 信')]",否则定位不到。 #以下定位是查找span标签有个文本(text)包含(contains)'写 信' 的元素,该定位方法重要 driver.find_element_by_xpath("//span[contains(text(),'写 信')]").click() #填写收件人 driver.find_element_by_class_name('nui-editableAddr-ipt').send_keys(r'xxx@163.com') #填写主题 #通过and连接更多的属性来唯一地标志一个元素 driver.find_element_by_xpath("//input[@class='nui-ipt-input' and @maxlength='256']").send_keys(u'自动化测试') #填写正文 #通过switch_to_frame()将当前定位切换到frame/iframe表单的内嵌页面中 driver.switch_to_frame(driver.find_element_by_class_name('APP-editor-iframe')) #在内嵌页面中定位邮件内容位置 emailcontext=driver.find_element_by_class_name('nui-scroll') #填写邮件内容 emailcontext.send_keys(u'这是第一封自动化测试邮件') #通过switch_to().default_content()跳回最外层的页面 #注:不要写成switch_to().default_content(),否则报AttributeError: SwitchTo instance has no __call__ method driver.switch_to.default_content() #driver.switch_to.parent_frame() #点击发送 time.sleep(3) #有可能存在元素不可见(查看元素是灰色的),会报ElementNotVisibleException错误 #包含发送二字的元素很多,所以还得再加上其他限制 #sendemails=driver.find_element_by_xpath("//span[contains(text(),'发送')]") sendemails=driver.find_element_by_xpath("//span[contains(text(),'发送') and @class='nui-btn-text']") time.sleep(3) #校验邮件是否发送成功 try: assert '发送成功' in driver.page_source except AssertionError: print '邮件发送成功' else: print '邮件发送失败' #调用退出模块 Login().user_logout(driver)
收信用例:
直接调用模块的登录和退出方法。
# coding=utf-8 ''' Created on 2016-7-27 @author: Jennifer Project:接收邮件 ''' from selenium import webdriver import time from test_5_2_public import Login driver=webdriver.Firefox() driver.implicitly_wait(30) driver.get(r'http://www.126.com/') #字符串加r,防止转义。 time.sleep(3) driver.switch_to.frame('x-URS-iframe') #调用登录模块 Login().user_login(driver) time.sleep(10) #接收邮件 #点击收信 #以下定位是查找span标签有个文本(text)包含(contains)'收 信' 的元素,该定位方法重要 driver.find_element_by_xpath("//span[contains(text(),'收 信')]").click() #校验是否进入收件箱,没报错即进入 try: #点击其中一封邮件 driver.find_element_by_xpath("//div[@sign='letter']").click() except Exception as e: print e else: print '成功收信' #调用退出模块 Login().user_logout(driver)
三,数据驱动测试
1.概念:
它将测试中的测试数据和操作分离,数据存放在另外一个文件中单独维护。
通过数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。
操作+重复操作+数据分开。
2.优点:
通过这种方式,将数据和重复操作分开,可以快速增加相似测试,完成不同数据情况下的测试。
3.缺点
暂无
4.实例
从excel表格读取用户名密码,登录邮箱。
以下的用户名密码到时候自己去申请,就不将笔者的用户密码贴出来了。
# coding=utf-8 ''' Created on 2016-7-28 @author: Jennifer Project:数据驱动测试,数据保存在excel中,需要导入xlrd模块 ''' from selenium import webdriver import time import xlrd #将用户密码表格转换为用户密码列表 def exceltolist(excelfile,colnameindex=0,by_index=0): excelfile=xlrd.open_workbook(excelfile) #打开excel表格 # table = excelfile.sheets()[by_index] #默认获取sheet0页 table = excelfile.sheet_by_index(by_index)#默认获取sheet0页 nrows=table.nrows #获取excel的sheet0页的行数 colnames=table.row_values(colnameindex) #默认获取第0行的列表数据:name和password两个值 list =[] #建一个空列表,用来存放用户密码字典 for rownum in range(1,nrows): #初始行为0,从第1行开始 row = table.row_values(rownum) #获取某一行的列表数据 if row: app = {} #建立一个空字典,存放某一组用户密码数据 for i in range(len(colnames)): #目前是2 app[colnames[i]] = row[i] #字典新增数据:循环两次,字典新增两对key-value list.append(app) #将新增的字典数据,添加到列表数据中 return list def Login(): file=r'D:\pythontest\rightpassword\userpassword.xls' userlist=exceltolist(file) for i in range(len(userlist)): driver=webdriver.Firefox() driver.get(r'http://www.126.com/') #字符串加r,防止转义。 time.sleep(3) driver.switch_to.frame('x-URS-iframe') #同上面语句一样,跳转到iframe框架 username=driver.find_element_by_name('email') username.clear() username.send_keys(userlist[i]['name']) time.sleep(0.1) userpasswd=driver.find_element_by_name('password') userpasswd.clear() userpasswd.send_keys(userlist[i]['password']) time.sleep(0.1) loginbt=driver.find_element_by_id('dologin') loginbt.click() time.sleep(3) try: assert '网易邮箱' in driver.title except AssertionError: print '用户%s邮箱登录失败'%(userlist[i]['name']) else: print '用户%s邮箱登录成功'%(userlist[i]['name']) finally: driver.quit() if __name__=='__main__': Login()
四,关键字驱动测试
关键字驱动的来源非常自然,从面向对象的思路出发,同样的业务逻辑会自然的编写成一个类或者函数作为关键字来被不同的测试脚本所调用。当测试框架发展到所有 的测试过程都已经可以被写好的函数和类所组合完成时,就进化到了关键字驱动的一个高级阶段,这个时候测试用例的开发就变成了测试数据和关键字的组合,并把 这种组合工作简化为所有人都很熟悉的表格填写任务,从而最终达到一个由数据和关键字驱动整个测试的效果。
在关键字驱动框架里,你可以创建一些关键字以及相关联的一些方法和函数。然后你创建一个函数库,它里面包含一个读取关键字的逻辑,然后调用相关的动作。
关键字驱动的自动化测试(也称为表驱动测试自动化),是数据驱动自动化测试的变种,可支持由不同序列或多个不同路径组成的测试。它是一种独立于应 用程序的自动化框架,在处理自动化测试的同时也要适合手工测试。关键字驱动的自动化测试框架建立在数据驱动手段之上,表中包含指令(关键词),而不只是数 据。这些测试被开发成使用关键字的数据表,它们独立于执行测试的自动化工具。关键字驱动的自动化测试是对数据驱动的自动化测试的有效改进和补充。
这种自动化测试的模型主要由核心数据驱动引擎、组件函数、支持库和应用映射表组成。自动化测试首先由初始脚本开始执行,这个脚本把高层测试表传递给高层驱 动器,高层驱动器在处理这些表的过程中,遇到中层测试表后就调用中层驱动器,中层驱动器处理中层表时也作类似的处理。当低层驱动器处理低层表时,它尝试着 使应用与测试保持同步。当低层驱动器遇到对某一个组件的低层关键字组件时,它判断这个组件的类型并调用相应的组件函数模块来处理这个指令操作。所有这些元 素都要依靠映射表中的信息,它是自动化测试模型和被测应用程序的桥梁。支持库主要完成一些文件处理,日志记录和邮件发送等等的功能。