unittest 运行slenium(三)---通过数据驱动形式运行用例
一: 获取数据
获取用例所在位置,通过OpenExcelPandas来读取用例里面的全部数据。通过某个列名来创建新的序号。
并将结果转换成list类型,将其作为ddt数据的来源。
1. 在test文件中调用数据驱动准备函数
excel_data = user_login.excel_to_list(user_login.login_excel, user_login.login_sheet, '序号')
2. 根据指定的用例来读取数据并转换成list
def get_ini_file(excel: str) -> str:
# 文件参数路径
argument = ReadModelIni(ini_name) # yaml读取用例位置
login_path = argument.get_value(cd_excel, cd_login)
module_path = argument.get_value(cd_excel, excel) module_excel_path = os.path.join(login_path, module_path)
return module_excel_path def excel_to_list(excel: str, sheet: str, title_name: str) -> list:
"""
读取用例
:return: 将数据转换成list进行返回
"""
excel_path = get_ini_file(excel)
# 读取相应路径中的数据
read = OpenExcelPandas(name=excel_path, sheet=sheet)
ex_data = read.internal_read_excel(title_name)
df_index = ex_data.index
ex_data = [ex_data.loc[df_i] for df_i in df_index]
return ex_data
二: 创建test
1. 类装饰器为@ddt.ddt
2. test函数装饰器为@ddt.data
3. 在test运行前需要创建test的操作类对象,并实例化日志对象。
4. 具体代码
import os
import inspect import unittest
import ddt from case.zentao import user_login
from business.zentao.login.user_login_business import UserLoginBusiness base_path = os.path.split(os.path.dirname(__file__))[1]
base_name = base_path + "-" + os.path.splitext(os.path.basename(__file__))[0] excel_data = user_login.excel_to_list(user_login.login_excel, user_login.login_sheet, '序号') @ddt.ddt
class TestLoginUser(unittest.TestCase): @classmethod
def setUpClass(cls) -> None:
cls.business_login = UserLoginBusiness(base_name)
pass def setUp(self) -> None:
self.business_login.create_browser()
pass def tearDown(self) -> None:
self.business_login.login_page.browser_action.close_driver_browser()
pass @ddt.data(*excel_data)
def test_run_login(self, case):
self.business_login.log.info("%s序号的用例开始运行" % case["序号"]) # 设置日志需要输出的函数名
self.business_login.log.fun_name = "%s-%s" % (inspect.stack()[0][3], case["序号"]) # 打印需要输出的内容
# self.business_login.log.info("用例中所以的内容为:%s" % case) # 定义第三方存储对象,可以让其它对象进行调用使用。
self.business_login.data_case_singe = case # 运行执行用例需要执行的动作
self.business_login.user_pass_error() self.business_login.log.info("%s序号的用例运行完毕" % case["序号"])
pass if __name__ == '__main__':
unittest.main(verbosity=2)
del excel_data
三: 创建page元素类
1. 该类存储当前页面所有的元素所在路径及路径类型
2. 在实例化时创建浏览器对象
3. 代码如下:
from util_tools.operation.action_interface import ActionParsing class UserLoginPage(object):
def __init__(self):
self.browser_action = ActionParsing()
pass def input_user_name(self, parameter) -> None:
"""
返回账号元素的类型及路径
:return:
"""
account = "id>>account"
self.browser_action.is_input_execute(account, parameter)
pass def input_pass_word(self, parameter) -> None:
"""
返回密码元素的类型及路径
:return:
"""
pass_word = "css>>input[type=password]"
self.browser_action.is_input_execute(pass_word, parameter)
pass def click_login_button(self) -> None:
"""
返回登录按钮元素的类型及路径
:return:
"""
button = "css>>.btn.btn-primary"
self.browser_action.is_click_execute(button)
pass def get_form_error(self) -> str:
"""
返回登录错误时系统弹窗提示语的类型及路径
:return:
"""
# form_error = "id>>formError"
# attr_text = self.browser_action.get_text_value(form_error)
# 获取弹窗对象
alert_pupop = self.browser_action.driver.switch_to.alert
# 获取弹窗内容
alert_text = alert_pupop.text
# 点击弹窗中的确定按钮
alert_pupop.accept()
return alert_text pass
四:test用例操作类
1. 该类主要是对用例执行的进行操作
2. 代码如下
from selenium.webdriver.support import expected_conditions as EC from util_tools.logger import Logger
from util_tools.storage.read_model_file import ReadModelIni
from pages.zentao.login.user_login_page import UserLoginPage
from case.zentao import user_login class UserLoginBusiness(object): def __init__(self, base_name: str):
"""
实例化对象,并且创建日志对象及元素操作对象
:param base_name: 用例运行类类名
"""
self.log = Logger(base_name)
self.login_page = UserLoginPage()
pass # ----------------- 将set跟get封装后由单个参数来实现 -----------------
def set_case(self, case):
self.case = case
pass def get_case(self):
return self.case data_case_singe = property(get_case, set_case, doc="找不到内容") # ----------------- -----------------
def create_browser(self):
# 获取需要打开的url
argument = ReadModelIni("system_settings.ini")
login_url = argument.get_value("wap_url", "zen_tao_url")
self.log.info("浏览器url :" + login_url) # 创建浏览器对象,并打开
self.login_page.browser_action.run_web_browser(login_url, user_login.login_browser, user_login.login_wait_time)
self.log.info("%s浏览器已经打开,显示时间为%ss" % (user_login.login_browser, user_login.login_wait_time)) def user_pass_error(self):
# 执行账号输入操作
self.login_page.input_user_name(self.data_case_singe["账号"])
# 执行密码输入操作
self.login_page.input_pass_word(self.data_case_singe["密码"])
# 判断是否需要点击登录按钮
login_button = self.data_case_singe["登录"]
if login_button.capitalize() in 'Y':
# 执行点击操作
self.login_page.click_login_button()
# 判断点击登录后的情况
login_follow = self.data_case_singe["后续"]
login_follow_label, login_follow_info = login_follow.split("-->")
if 'error' in login_follow_label:
# 账号密码错误时,提示语的判断。
attr_text = self.login_page.get_form_error()
assert attr_text in login_follow_info, "登录失败时,提示语判断错误。"
self.log.info("登录失败的原因为:%s" % login_follow_info)
pass
elif 'go' in login_follow_label:
# 点击登录后跳转的页面
assert EC.title_contains(login_follow_info), "页面已经发生跳转并不在登录页面"
pass
else:
self.log.info("点击登录后,excel中的后续编写有误:%s" % login_follow)
pass
else:
self.log.info("不需要点击登录按钮")
pass pass
项目所在位置:
https://github.com/namexiaohuihui/demotest
unittest 运行slenium(三)---通过数据驱动形式运行用例的更多相关文章
- unittest 运行slenium(四)---通过指定用例的形式运行用例
一: 说明 跟数据驱动唯一的区别为用例数据获取时,及运行方式不同. 其它都基本相同,可参考https://www.cnblogs.com/xiaodingdong/p/11753220.html 二: ...
- unittest 运行slenium(五)---运行代码并生成HTMLTestRunner报告
整体代码如下: import os import sys import time import datetime import unittest import HTMLTestRunner # git ...
- AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(三):配置ActiveXForm运行环境
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- Python逆向(三)—— Python编译运行及反汇编
一.前言 前期我们已经对python的运行原理以及运行过程中产生的文件结构有了了解.本节,我们将结合具体的例子来实践python运行,编译,反编译的过程,并对前些章节中可能遗漏的具体细节进行补充. 二 ...
- 进程,多进程,进程与程序的区别,程序运行的三种状态,multiprocessing模块中的Process功能,和join函数,和其他属性,僵尸与孤儿进程
1.进程 什么是进程: 一个正在被运行的程序就称之为进程,是程序具体执行的过程,是一种抽象概念,进程来自操作系统 2.多进程 多个正在运行的程序 在python中实现多线程的方法 from mult ...
- 《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态
1. 简介 今天北京下的雪好大好美啊!!!哎呀,忘记拍照片了,自己想象一下吧.言归真传,今天还是开始pytest的学习和修炼,上一篇写完后群里反响各式各样的,几家欢乐几家愁,有的高兴说自己刚好要用到了 ...
- dubbo服务运行的三种方式
dubbo服务运行,也就是让生产服务的进程一直启动.如果生产者进程挂掉,也就不存在生产者,消费者不能进行消费. Dubbo服务运行的三种方式如下:1.使用Servlet容器运行(Tomcat.Jett ...
- Tomcat Connector的三种不同的运行模式
Tomcat Connector的三种不同的运行模式性能相差很大,有人测试过的结果如下: 这三种模式的不同之处如下: BIO: 一个线程处理一个请求.缺点:并发量高时,线程数较多,浪费资源. Tomc ...
- 【dubbo】服务提供者运行的三种方式
[dubbo]服务提供者运行的三种方式 学习了:https://blog.csdn.net/yxwb1253587469/article/details/78712451 1,使用容器: 2,使用自建 ...
随机推荐
- Delphi XE6 使用定时器或者线程解决程序界面无响应问题
---恢复内容开始--- 介绍 在手机应用上,我们不应该使用速度慢的代码,当然我们在桌面程序上也应该避免这个,当手机应用长时间没有相应的时候,程序会提示“程序没响应,是否关闭”的提示,这个非常不好,所 ...
- POJ Corn Fields 状态压缩DP基础题
题目链接:http://poj.org/problem?id=3254 题目大意(名称什么的可能不一样,不过表达的意思还是一样的): 种玉米 王小二从小学一年级到现在每次考试都是班级倒数第一名,他的爸 ...
- H310C,B365,M.2 NVME SSD,USB3.0,安装 WIN7 64 位
华擎H310CM ITX NVME SSD 上安装WIN7 64位 核心关键点:xHCI USB3.0驱动,nvme驱动,nvme win7补丁. 硬件配置:I5 9400F, 华擎H310CM IT ...
- SELinux安全子系统的学习
SELinux(Security-Enhanced Linux)是美国国家安全局在 Linux 开源社区的帮助下开发的 一个强制访问控制(MAC,Mandatory Access Control)的安 ...
- 【Luogu P3919】可持久化数组
数组是一种单点修改,单点查询的基础数据结构. 如果要对数组改进,使之可持久化,那么显然我们需要利用其它的数据结构来改进它. 对于单点修改和单点查询两种操作,很容易发现可持久化线段树也是支持这种操作的. ...
- visual studio 2017搭建linux c++开发环境
https://blog.csdn.net/cekonghyj/article/details/77917433 https://blog.csdn.net/norsd/article/details ...
- 史上最浅显易懂的RxJava入门教程
RxJava是一个神奇的框架,用法很简单,但内部实现有点复杂,代码逻辑有点绕.我读源码时,确实有点似懂非懂的感觉.网上关于RxJava源码分析的文章,源码贴了一大堆,代码逻辑绕来绕去的,让人看得云里雾 ...
- 学习开始记录一下,java 还是python?
2019.11.24开始正式开始学习JAVA. 在 bilibili站看了三天,大神们的对此问题的分析,介绍,我选择了JAVA开发语言. 在看了高淇老师的JAVA300视频,感觉比较对路,特别是第一章 ...
- jenkins【目录】:目录
jenkins[目录]:目录 GitLab 自动触发 Jenkins 构建 返回
- LeetCode 680. 验证回文字符串 Ⅱ(Valid Palindrome II) 1
680. 验证回文字符串 Ⅱ 680. Valid Palindrome II 题目描述 给定一个非空字符串 s,最多删除一个字符.判断是否能成为回文字符串. 每日一算法2019/5/4Day 1Le ...