按自动化测试的发展顺序,主要以下几种模型:
- 线性模型:按顺序编写操作步骤产生线性脚本,每个线性脚本相对独立,且不产生依赖与调用。开发维护成本高(例如登录的重复操作,每个脚本都需要开发和维护)
- 模块化驱动测试:借鉴编程语言中模块化思想,把重复的操作单独封装成公共模块。当需要用到封装的模块时对其进行调用,这样就极大限度的消除重复,从而提高测试用例的可维护性。
- 数据驱动测试:数据的改变驱动自动化测试的执行,最终引起测试结果的改变。简单理解就是把数据驱动所需要的测试数据参数化,我们可以用多种方式来存储和管理这些参数化的数据。例如:可以通过定义变量、数组、字典、外部文件(excel、csv、txt、xml等)
- 关键字驱动测试:典型的工具如QTP、seleniumIDE等
下面主要介绍模块化驱动测试和数据驱动测试:
模块化与参数化一般配合使用,即在创建函数或类方法时为它们设置入参,从而使它们可以根据不同的参数执行相应的操作
1. 模块化驱动测试
将重复的操作独立成公共模块,如下:
a)传统的线性模型
from selenium import webdriver import time driver = webdriver.Chrome() driver.get('http://www.baidu.com') driver.find_element_by_id('kw').send_keys('python') driver.find_element_by_id('su').click() time.sleep(3) driver.quit()
b)将搜索功能,封装成函数
test_baidu.py
class TestBaidu(): # 1.创建一个TestBaidu类 def __init__(self, driver): # 2.在__init__初始化方法中接收driver驱动,并赋值给self.driver self.driver = driver def test_baidu_search(self): # 在功能测试方法中,使用self.driver self.driver.find_element_by_id('kw').send_keys('python') self.driver.find_element_by_id('su').click() def test_quit(self): self.driver.quit()
runtest.py
from selenium import webdriver from test_baidu import TestBaidu # 导入TestBaidu类 import time driver = webdriver.Chrome() driver.get('http://www.baidu.com') test_baidu = TestBaidu(driver) # 创建TestBaidu类的对象,并传入driver驱动 test_baidu.test_baidu_search() # 调用test_baidu_search()方法,进行功能测试 time.sleep(3) test_baidu.test_quit() # 调用test_quit()方法,退出并关闭浏览器
c)对test_baidu_search()方法进行参数化
例如,想要进行不同关键字的查询
test_baidu.py
class TestBaidu(): def __init__(self, driver): self.driver = driver def test_baidu_search(self, keyword): # 增加参数keyword self.driver.find_element_by_id('kw').clear() self.driver.find_element_by_id('kw').send_keys(keyword) self.driver.find_element_by_id('su').click() def test_quit(self): self.driver.quit()
runtest.py
from selenium import webdriver from test_baidu import TestBaidu import time driver = webdriver.Chrome() driver.get('http://www.baidu.com') test_baidu = TestBaidu(driver) keyword1 = 'python' test_baidu.test_baidu_search(keyword1) # 传入keyword1,搜索关键词1 time.sleep(3) keyword2 = 'selenium' test_baidu.test_baidu_search(keyword2) # 传入keyword2,搜索关键词2 time.sleep(3) test_baidu.test_quit()
2. 数据驱动测试
实际上,常把测试数据放到数据文件中 ,下面介绍各种类型的数据文件的读取
a)读取txt文件
如果有多个字段,则字段间用逗号“,”隔开,代码中使用split分割(注意最后一行,有一个空行),txt文件如下:
读取文件代码如下(读取内容写入user_list列表中):
with open('./data/user_info.txt', 'r') as file: data = file.readlines() user_list = [] for line in data: user_list.append(line[:-1].split(','))
# [:-1]对字符串进行切片,去掉最后一个字符(每行结尾的换行符 ) # split(',')通过逗号对数据进行拆分,得到一个列表 # data: ['hunanyaodian01,a123456 ', 'hunanyaodian02,a123456 ', 'hunanyaodian03,a123456 '] # user_list:[['hunanyaodian01', 'a123456'], ['hunanyaodian02', 'a123456'], ['hunanyaodian03', 'a123456']]
b)读取csv文件
可以通过创建Excel表格,另存为CSV(不要直接修改文件后缀名,那不是真正的csv文件),文件如下:
读取文件代码如下(读取内容写入user_list列表中):
import csv # 导入csv包 from itertools import islice # 导入islice(用于操作迭代对象) # 读取本地csv文件 data = csv.reader(open('./data/ddf.csv', 'r')) users = [] for line in islice(data, 1, None): # 跳过文件第一行 islice(迭代对象,开始位置,结束位置) users.append(line) print(users) # 打印 [['', '123', '请输入账号'], ['user', '', '请输入密码'], ['error', 'error', '账号或密码错误'], ['admin', 'admin123', 'admin你好']]
读取的数据以数组的形式存储,若想取某一列数据,只需指定下标即可
c)读取xml文件
有时我们读取的数据是不规则的。例如:我们用一个配置文件来配置当前自动化测试平台、浏览器、URL、登录的用户名密码等,这时就用xml文件来存放这些测试数据。
数据存放形式:
- 标签对之间
- 作为标签的属性
一个简单的xml文件如下:
<?xml version="1.0" encoding="utf-8" ?> <info> <platforms> <platform>Windows</platform> <platform>Linux</platform> <platform>macOS</platform> </platforms> <browsers> <browser>Firefox</browser> <browser>Chrome</browser> <browser>Edge</browser> </browsers> <url>http://www.baidu.com</url> <login username="admin" password="123456"/> <login username="guest" password="123456"/> </info>
读取标签对之间的数据:
from xml.dom.minidom import parse # 打开xml文件 dom = parse('./data/config.xml') # 得到文档元素对象 root = dom.documentElement # 获取一组标签(不需要指定标签的层级关系,即获取的标签可以是任意层级的。xml中的层级仅是为了阅读方便) tag_name = root.getElementsByTagName('platform') # 获取标签中的某个元素(firstChild返回被选节点的第一个子节点,data表示获取该节点的数据) print(tag_name[0].firstChild.data) # 打印 Windows print(tag_name[1].firstChild.data) # 打印 Linux print(tag_name[2].firstChild.data) # 打印 macOS
读取标签的属性值:
from xml.dom.minidom import parse dom = parse('./data/config.xml') root = dom.documentElement login_info = root.getElementsByTagName('login') username = login_info[0].getAttribute('username') # 获取第一个login标签的username属性值 print(username) # 打印 admin passwd = login_info[0].getAttribute('password') # 获取第一个login标签的password属性值 print(passwd) # 打印 123456 username = login_info[1].getAttribute('username') print(username) # 打印 guest passwd = login_info[1].getAttribute('password') print(passwd) # 打印 123456
d)读取json文件
json文件如下:
代码如下:
import json with open('./data/user_info.json', 'r') as file: data = file.read() user_list = json.loads(data) # 将str类型转换list类型 print(user_list) # 打印 [{'username': '', 'password': ''}, {'username': '', 'password': '123'}, {'username': 'user', 'password': ''}, {'username': 'error', 'password': 'error'}, {'username': 'admin', 'password': 'admin123'}]
通过open()方法即可读取json文件。因为测试数据本身是以列表和字典形式存放的,所以读取整个文件内容后,通过json提供的表将str类型转换为list类型即可
ps:自动化测试中,数据驱动必须和单元测试框架一起讨论才有意义