WebUI自动化框架 - 数据驱动(ddt、paramunittest)
数据驱动
- 数据驱动测试时自动化测试中的主流设计模式之一,属于中级自动化测试工程师必备知识,必须深入掌握数据驱动测试的工作原理和实现方法
概述:
- 所谓数据驱动,时指相同的测试脚本使用不同的测试数据来执行,测试数据与测试行为完全分离,这样的测试脚本设计模式称为数据驱动。例如,测试网站的登录功能,自动化测试工程师想验证不同的用户名和密码在网站登录时对系统影响结果,就可以使用数据驱动模式来进行自动化模式
实现数据驱动测试步骤如下:
- 编写测试脚本,脚本需要支持从程序对象、文件或数据库读入测试数据
- 将测试脚本使用的测试数据存入程序对象、文件或数据库等外部介质中
- 运行脚本过程中,循环调用存储在外部介质中的测试数据
- 验证所有的测试结果是否符合预期结果
使用 unittest 结合 ddt 进行数据驱动
使用 unittest 单元测试框架进行数据驱动的话需要引入 ddt 模块
import ddt
测试用例逻辑:
打开百度首页
在搜索狂中输入一个关键词
单击搜索按钮
验证搜索结果页面是否包含预期关键字符串
unittest 结合 dtt 代码示例
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import unittest
import ddt
import time@ddt.ddt
class TestDemo(unittest.TestCase):def setUp(self) -> None:self.driver = webdriver.Chrome()self.driver.get('https://www.baidu.com/')self.driver.maximize_window()self.driver.implicitly_wait(30)@ddt.data(["大话西游之月光宝盒", "周星驰"],["飞驰人生", "沈腾"],["夏洛特烦恼", "马丽"])@ddt.unpack # 先不加unpack试试效果def test_search(self, keyword, expected):try:self.driver.find_element_by_id('kw').send_keys(keyword)self.driver.find_element_by_id('su').click()time.sleep(3)self.assertTrue(expected in self.driver.page_source)except NoSuchElementException as e:print("查找的页面元素不存在,Error:{}".format(e))except AssertionError as e:print("断言错误,搜索:{},期望:{}".format(keyword, expected))except Exception as e:print(e)def tearDown(self) -> None:time.sleep(3)self.driver.quit()if __name__ == '__main__':unittest.main()
要点:
- 必须引入 ddt 模块
- 需要声明使用 @ddt.ddt
- 在测试方法前使用 @ddt.data()添加所需要的数据(可迭代对象),多组数据间以逗号“,”隔开,以此判断执行的次数
- 如果每组测试数据存在多个测试数据,需要将每组数据存于列表中
- 每组数据中的数据与测试方法中定义的形参个数及顺序一一对应
- 使用 unpack 进行解包操作
使用json数据文件进行数据驱动
data.json文件
["邓肯||蒂姆","詹姆斯||勒布朗","杜兰特||凯文","乔丹||迈克尔","库里||史蒂芬"
]
sample.py文件
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import HTMLTestRunner
import unittest
import ddt
import logging
import time
import oslogging.basicConfig(level=logging.INFO,format="%(asctime)s - %(filename)s - %(levelname)s - %(message)s",datefmt='%a, %Y - %m - %d %H: %M: %S',
)@ddt.ddt
class TestDemo(unittest.TestCase):@classmethoddef setUpClass(cls) -> None:logging.info("测试开始啦")def setUp(self) -> None:self.driver = webdriver.Chrome()self.driver.get('https://www.baidu.com/')self.driver.maximize_window()self.driver.implicitly_wait(30)@ddt.file_data("data.json")@ddt.unpackdef test_search(self, value):keyword, expected = tuple(str(value).strip().split("||"))try:self.driver.find_element_by_id('kw').send_keys(keyword)self.driver.find_element_by_id('su').click()logging.info("打开百度,搜索关键词:{},期望返回:{}".format(keyword, expected))time.sleep(3)self.assertTrue(expected in self.driver.page_source)logging.info("{} 存在于页面资源中,断言通过".format(expected))except NoSuchElementException as e:logging.error("查找的页面元素不存在,Error:{}".format(e))except AssertionError as e:logging.error("断言错误!搜索:{},期望:{}".format(keyword, expected))except Exception as e:logging.error(e)def tearDown(self) -> None:time.sleep(3)self.driver.quit()@classmethoddef tearDownClass(cls) -> None:logging.info("测试结束啦!请查看测试报告哟!爱你哟!")if __name__ == '__main__':# unittest.main()# 基础项目路径BASE_DIR = os.path.dirname(os.path.abspath(os.path.split(os.path.realpath(__file__))[-2]))print(BASE_DIR)# 用例存放路径CASE_DIR = os.path.join(BASE_DIR, 'case')# 报告存放路径REPORT_DIR = os.path.join(BASE_DIR, 'report')# 构建完整报告路径report_path = REPORT_DIR + "\\" + time.strftime("%Y-%m-%d-%H-%M") + ".html"print(report_path)# 创建测试套件suit = unittest.TestSuite()# 发现测试用例testcase = unittest.defaultTestLoader.discover(CASE_DIR)suit.addTests(testcase)# 必须线打开文件,才能写入数据with open(report_path, mode='wb') as fp:# 实例化HTMLTestRunner类,并传入指定参数runner = HTMLTestRunner.HTMLTestRunner(stream=fp,verbosity=2,title="百度搜索测试",description="春天真美呀,夏天真热呀,秋天真爽呀,冬天真冷呀")# 执行runner.run(suit)
使用YAML数据文件进行数据驱动
yaml文件:data.yaml
-keyword: 刘亦菲expected: 刘亦菲-keyword: 赵丽颖expected: 赵丽颖-keyword: 林俊杰expected: 林俊杰
python文件:test_demo.py
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import HTMLTestRunner
import unittest
import ddt
import logging
import time
import oslogging.basicConfig(level=logging.INFO,format="%(asctime)s - %(filename)s - %(levelname)s - %(message)s",datefmt='%a, %Y - %m - %d %H: %M: %S',
)@ddt.ddt
class TestDemo(unittest.TestCase):@classmethoddef setUpClass(cls) -> None:logging.info("测试开始啦")def setUp(self) -> None:self.driver = webdriver.Chrome()self.driver.get('https://www.baidu.com/')self.driver.maximize_window()self.driver.implicitly_wait(30)@ddt.file_data("data.yaml")def test_search_word(self, **kwargs):keyword = kwargs.get('keyword')expected = kwargs.get('expected')print(keyword)print(expected)try:self.driver.find_element_by_id('kw').send_keys(keyword)self.driver.find_element_by_id('su').click()logging.info("打开百度,搜索关键词:{},期望返回:{}".format(keyword, expected))time.sleep(3)self.assertTrue(expected in self.driver.page_source)logging.info("{} 存在于页面资源中,断言通过".format(expected))except NoSuchElementException as e:logging.error("查找的页面元素不存在,Error:{}".format(e))except AssertionError as e:logging.error("断言错误!搜索:{},期望:{}".format(keyword, expected))except Exception as e:logging.error(e)def tearDown(self) -> None:time.sleep(3)self.driver.quit()@classmethoddef tearDownClass(cls) -> None:logging.info("测试结束啦!请查看测试报告哟!爱你哟!")if __name__ == '__main__':unittest.main()
使用EXCEL数据文件进行数据驱动
解析EXCEL文件的类:excel_util
from openpyxl import load_workbookclass ParExcel(object):def __init__(self, excel_path, sheet_name):self.wb = load_workbook(excel_path)self.sheet = self.wb[sheet_name]self.max_row_num = self.sheet.max_rowself.max_row_column = self.sheet.max_columndef get_data_from_sheet(self):# 用于存放工作表中读取出来的数据data_list = []for line in self.sheet.rows:# 遍历工作表中数据区域的每一行# 并将每行中各个单元格的数据取出存于tmp_list中# 最后添加进data_list,并返回# print(line.)tmp_list = list()tmp_list.append(line[0].value)tmp_list.append(line[1].value)data_list.append(tmp_list)data_list.pop(0)return data_listif __name__ == '__main__':pe = ParExcel('C:\\Users\\Administrator\\Desktop\\data.xlsx', '搜索数据表')data = pe.get_data_from_sheet()print(data)
测试用例文件:test_sample.py
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import unittest
import ddt
import logging
import time
from excel_util import ParExcelexcel_data = ParExcel('C:\\Users\\Administrator\\Desktop\\data.xlsx', '搜索数据表').get_data_from_sheet()
print(*excel_data)logging.basicConfig(level=logging.INFO,format="%(asctime)s - %(filename)s - %(levelname)s - %(message)s",datefmt='%a, %Y - %m - %d %H: %M: %S',
)@ddt.ddt
class TestDemo(unittest.TestCase):@classmethoddef setUpClass(cls) -> None:logging.info("测试开始啦")def setUp(self) -> None:self.driver = webdriver.Chrome()self.driver.get('https://www.baidu.com/')self.driver.maximize_window()self.driver.implicitly_wait(30)@ddt.data(* excel_data)def test_search(self, keyword, expected):try:self.driver.find_element_by_id('kw').send_keys(keyword)self.driver.find_element_by_id('su').click()logging.info("打开百度,搜索关键词:{},期望返回:{}".format(keyword, expected))time.sleep(3)self.assertTrue(expected in self.driver.page_source)logging.info("{} 存在于页面资源中,断言通过".format(expected))except NoSuchElementException as e:logging.error("查找的页面元素不存在,Error:{}".format(e))except AssertionError as e:logging.error("断言错误!搜索:{},期望:{}".format(keyword, expected))except Exception as e:logging.error(e)def tearDown(self) -> None:time.sleep(3)self.driver.quit()@classmethoddef tearDownClass(cls) -> None:logging.info("测试结束啦!请查看测试报告哟!爱你哟!")if __name__ == '__main__':unittest.main()
使用 unittest 结合 paramunittest 进行数据驱动
- paramunittest是unittest实现参数化的一个专门的模块,可以传入多组参数,自动生成多个用例,前面讲数据驱动的时候,用ddt可以解决多组数据传入,自动生成多个测试用例。现在继续介绍另外一个参数化的框架paramunittest,也能实现一样的效果。
导入模块
pip install paramunittest
代码示例
import unittest
import paramunittestlist_ = [('1', '2'),# (4, 3),('2', '3'),
]@paramunittest.parametrized(*list_)
class TestFoo(paramunittest.ParametrizedTestCase):def setParameters(self, a, b):self.a = aself.b = bdef testLess(self):self.assertLess(self.a, self.b)@paramunittest.parametrized(('1', '2'),# (4, 3),('2', '3'),
)
class TestBar(unittest.TestCase):def setParameters(self, a, b):self.a = aself.b = bdef testLess(self):self.assertLess(self.a, self.b)if __name__ == '__main__':unittest.main(verbosity=2)
业务代码示例
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import unittest
import paramunittest
import time@paramunittest.parametrized(["大话西游之月光宝盒", "周星驰"],["飞驰人生", "沈腾"],["夏洛特烦恼", "马丽"])
class TestDemo(paramunittest.ParametrizedTestCase):# 参数名称与parametrized中的顺序和数量必须保持一致def setParameters(self, keyword, expected):self.keyword = keywordself.expected = expecteddef setUp(self) -> None:self.driver = webdriver.Chrome()self.driver.get('https://www.baidu.com/')self.driver.maximize_window()self.driver.implicitly_wait(30)def test_search(self):try:self.driver.find_element_by_id('kw').send_keys(self.keyword)self.driver.find_element_by_id('su').click()time.sleep(3)self.assertTrue(self.expected in self.driver.page_source)except NoSuchElementException as e:print("查找的页面元素不存在, Error:{}".format(e))except AssertionError as e:print("断言错误,搜索: {}, 期望: {}, Error: {}".format(self.keyword, self.expected, e))except Exception as e:print(e)def tearDown(self) -> None:time.sleep(3)self.driver.quit()if __name__ == '__main__':unittest.main(verbosity=2)
WebUI自动化框架 - 数据驱动(ddt、paramunittest)相关推荐
- Python+Selenium WebUI自动化框架 -- 实现特殊PO模型
前言: 设计执行格式,封装PO模型工厂,实现PO模型脱离代码,一套代码执行所有项目的UI自动化,让UI自动化框架脱离高成本.低效率时代,将用例的重用性贯彻到极致,让烦人的PO模型变得无所谓,让一个测试 ...
- RobotFramework自动化框架—数据驱动测试
前情介绍: 在自动化测试框架中,数据驱动的意思是指定的是测试用例或者说测试套件是由外部数据集合来驱动的框架. 数据集合(也可称之为数据来源)可以是任何类型的数据文件比如xls,xlsx,csv等等,甚 ...
- python自动化框架测试实操_自动化框架之 python+selenium+pytest
1.概述 selenium: 基于JavaScript代码库的自动化测试框架,通过脚本语言,模拟用户行为操作,最接近用户真实场景,实现对web自动测试. Selenium,是目前的最火爆企业最主流的w ...
- 基于Python的接口自动化unittest测试框架和ddt数据驱动详解
引言 在编写接口自动化用例时,我们一般针对一个接口建立一个.py文件,一条接口测试用例封装为一个函数(方法),但是在批量执行的过程中,如果其中一条出错,后面的用例就无法执行,还有在运行大量的接口测试用 ...
- 自动化测试框架cucumber_基于Cucumber和Testng的WebUI自动化测试方法与流程
本发明涉及计算机技术领域,具体的说是基于Cucumber和Testng的WebUI自动化测试方法. 背景技术: 行为驱动测试方法已经在敏捷开发模式中普遍使用,通过使用标准化的语言将客户需求人员.开发人 ...
- UI自动化框架 基于selenium+pytest和PO分层思想
最近在编写UI自动化框架,现在将一些碎片化东西进行梳理,便于记忆 同时,为了方便于各个模块的独立管理,以及秉承高复用,低耦合的思想,这里是根据PO模型编写,同时将所有的模块进行了独立,页面和元素,以及 ...
- Python 从无到有搭建WebUI自动化测试框架
目录 前言 1.Python库选择 2.分层设计 3.基础类 浏览器 页面操作 4.公共类 获取框架项目目录的绝对路径 编辑 读取excel用例 读取config配置 核心处理工厂 ddt驱动代码 ...
- Pytest 测试框架——数据驱动
引言 前面已经和大家介绍过 Unittest 测试框架的数据驱动框架 DDT,以及其实现原理.今天和大家分享的是 Pytest 测试框架的数据驱动,Pytest 测试框架的数据驱动是由 pytest ...
- 自动化框架搭建面试题
面试 1.接口自动化和web自动化有多少case ?覆盖率是多少?全部执行完需要多久? 2.接口自动化测试怎么做? web自动化测试怎么做? 3.什么是POM模式?为什么要使用它? 4.说说你对数据驱 ...
最新文章
- LaTeX入门最终集 :LaTeX格式的调整LaTeX中怎么打出数学公式LaTeX的各种上下标
- NVisionXR_iOS教程六 —— 场景中对象交互
- 组合恒等式7 组合变换的互逆公式 简介与简单例子
- 关于webcontrols的TreeView中转义符的处理问题
- 将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其他的空间。表中不允许又重复的数据
- j@2ff4f00f_J4F的完整形式是什么?
- tomcat常用功能
- linux模式匹配运算符,linux之正则表达式
- vscode 新版eslint自动修复_程序员请收好:10 个实用的 VS Code 插件
- Eclipse中的SVN插件
- caffe 实践程序4——cifar10网络
- 由一个国标文件中,英文名与中文意思的对比,看用词的重要性
- 【目标定位】基于matlab循环增益卡尔曼滤波目标定位仿真【含Matlab源码 145期】
- Fiddler4安装与配置_偷懒的肥猫
- GULP案例1:计算声子色散曲线和态密度
- vmware 安装报错:failed to install hcmon drivers 完美解决(含VMware15激活码)
- 电脑爱好者 2008年第24期 12月下
- python怎么识别拼音-python+拼音
- 服务器显示cpu温度高,高手教你巧解cpu温度过高问题
- 方舟服务器显示mod不符,方舟生存进化mod不符怎么办