1.基本概念
(1)库
库的英文单词是 Library,库是由代码集合成的一个产品,可供程序员调用。面向对象的代码组织形成的库叫类库,面向过程的代码组织形成的库叫函数库。
WebDriver 就属于库的范畴,因为它提供了一组操作 Web 页面的类与方法,所以可以称它为 Web 自动化测试库。
(2)框架
框架的英文单词是 Framework,框架是为解决一个或一类问题而开发的产品,用户一般只需使用框架提供的类或函数,即可实现全部功能。
unittest 框架主要用于测试用例的组织和执行,以及测试结果的生成。因为它的主要任务就是帮助我们完成测试工作,所以通常称它为测试框架。
(3)工具
工具的英文单词是 Tools,工具与框架所做的事情类似,只是工具提供了更高层次的封装,屏蔽了底层的代码,提供了单独的操作界面供用户使用。例如,UFT(QTP)、Katalon就属于自动化测试工具。
2.自动化测试模型
(1)线性测试
通过录制或编写对应用程序的操作步骤会产生相应的线性脚本,每个线性脚本相对独立,且不产生依赖与调用。这是早期自动化测试的一种形式,即单纯地模拟用户完整的操作场景。第4篇文章内容的自动化测试例子就属于线性测试。
(2)模块化与类库
线性测试的缺点是不易维护,故出现了新的自动化测试模型来代替线性测试。
该模型借鉴了编程语言中的模块化思想,把重复的操作单独封装成公共模块。在测试用例执行过程中,当需要用到模块封装时对其进行调用,这样就最大限度地消除了重复,从而提高测试用例的可维护性。
(3)数据驱动测试
模块化测试也有不足之处,例如在测试不同用户登录时,虽然登录的步骤是一样的,但是登录用的数据是不同的。模块化测试并不能解决这类问题。于是,数据驱动测试的概念被提出。
数据驱动测试的定义:数据的改变驱动自动化测试的执行,最终引起测试结果的改变。简单理解就是把数据驱动所需要的测试数据参数化,我们可以用多种方式来存储和管理这 些参数化的数据。
(4)关键字驱动测试
关键字驱动测试又被称为表驱动测试或基于动作字测试。这类框架会把自动化操作封装为“关键字”,避免测试人员直接接触代码,多以“填表格”的形式降低脚本的编写难度。
Robot Framework 是主流的关键字驱动测试框架之一,通过它自带的 Robot Framework RIDE 编写自动化测试用例。
这几种测试模型并非后者淘汰前者的关系,在实际实施过程中,往往需要相互结合使用。
3.模块化与参数化
模块化与参数化一般需要配合使用,即在创建函数或类方法时为它们设置入参,从而使它们可以根据不同的参数执行相应的操作。
创建一个邮箱测试脚本 test_mail.py
from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.126.com")
# 登录
sleep(2)
frame = driver.find_element_by_css_selector("iframe[id^='x-URS-iframe']")
driver.switch_to.frame(frame) # 默认直接传入id或name属性值
driver.find_element_by_name('email').clear()
driver.find_element_by_name('email').send_keys('username')
driver.find_element_by_name('password').click()
driver.find_element_by_name('password').send_keys('password')
driver.find_element_by_id('dologin').click()
# 登录之后的动作
driver.find_element_by_link_text('退出').click()
driver.switch_to.default_content()
driver.quit()
假设要实现一个关于邮箱的自动化测试项目,那么可能每条测试用例都需要有登录动作和退出动作。。此时,需要创建一个新的 module.py 文件来存放登录动作和退出动作。代码如下:
class Mail:
def __init__(self, driver):
self.driver = driver
def login(self):
self.driver.switch_to.frame()
frame = self.driver.find_element_by_css_selector("iframe[id^='x-URS-iframe']")
self.driver.switch_to.frame(frame) # 默认直接传入id或name属性值
self.driver.find_element_by_name('email').clear()
self.driver.find_element_by_name('email').send_keys