一: 获取数据

获取用例所在位置,通过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(三)---通过数据驱动形式运行用例的更多相关文章

  1. unittest 运行slenium(四)---通过指定用例的形式运行用例

    一: 说明 跟数据驱动唯一的区别为用例数据获取时,及运行方式不同. 其它都基本相同,可参考https://www.cnblogs.com/xiaodingdong/p/11753220.html 二: ...

  2. unittest 运行slenium(五)---运行代码并生成HTMLTestRunner报告

    整体代码如下: import os import sys import time import datetime import unittest import HTMLTestRunner # git ...

  3. AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(三):配置ActiveXForm运行环境

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  4. Python逆向(三)—— Python编译运行及反汇编

    一.前言 前期我们已经对python的运行原理以及运行过程中产生的文件结构有了了解.本节,我们将结合具体的例子来实践python运行,编译,反编译的过程,并对前些章节中可能遗漏的具体细节进行补充. 二 ...

  5. 进程,多进程,进程与程序的区别,程序运行的三种状态,multiprocessing模块中的Process功能,和join函数,和其他属性,僵尸与孤儿进程

    1.进程 什么是进程: 一个正在被运行的程序就称之为进程,是程序具体执行的过程,是一种抽象概念,进程来自操作系统 2.多进程  多个正在运行的程序 在python中实现多线程的方法 from mult ...

  6. 《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态

    1. 简介 今天北京下的雪好大好美啊!!!哎呀,忘记拍照片了,自己想象一下吧.言归真传,今天还是开始pytest的学习和修炼,上一篇写完后群里反响各式各样的,几家欢乐几家愁,有的高兴说自己刚好要用到了 ...

  7. dubbo服务运行的三种方式

    dubbo服务运行,也就是让生产服务的进程一直启动.如果生产者进程挂掉,也就不存在生产者,消费者不能进行消费. Dubbo服务运行的三种方式如下:1.使用Servlet容器运行(Tomcat.Jett ...

  8. Tomcat Connector的三种不同的运行模式

    Tomcat Connector的三种不同的运行模式性能相差很大,有人测试过的结果如下: 这三种模式的不同之处如下: BIO: 一个线程处理一个请求.缺点:并发量高时,线程数较多,浪费资源. Tomc ...

  9. 【dubbo】服务提供者运行的三种方式

    [dubbo]服务提供者运行的三种方式 学习了:https://blog.csdn.net/yxwb1253587469/article/details/78712451 1,使用容器: 2,使用自建 ...

随机推荐

  1. 【helm & Tiller】报错Error: incompatible versions client[v2.14.1] server[v2.13.0] │

    helm是helm的客户端部分 tiller是helm的服务器端部分 报错 报错Error: incompatible versions client[v2.14.1] server[v2.13.0] ...

  2. SourceTree 免登录跳过初始设置的方法 for Windows

    SourceTree安装包下载地址: 链接: https://pan.baidu.com/s/1rOPQkfNqvLGcIeZNw0aAjw 密码: 42us nodev6.9.0 和git 链接:h ...

  3. Mysql 千万数据快速导入

    最近碰到个项目,需要 千万条数据入库的问题,有原本的 类 csv 文件导入, 统计了下  数据行大概有 1400W 行之多 二话不说, 建表,直接 load LOAD DATA LOCAL INFIL ...

  4. LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)

    104. 二叉树的最大深度 104. Maximum Depth of Binary Tree 题目描述 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说 ...

  5. [转帖]iis最大并发连接数、队列长度、最大并发线程数、最大工作进程数

    iis最大并发连接数.队列长度.最大并发线程数.最大工作进程数 2018-10-17 12:49:03 牛兜兜 阅读数 2952   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议 ...

  6. CentOS 7 下安装 MySQL 5.7

    从 CentOS 7 系统开始,MariaDB 成为 yum 源中默认的数据库安装包.在 CentOS 7 及以上的系统中使用 yum 安装 MySQL 包将无法使用 MySQL.您可以选择使用完全兼 ...

  7. Linux 实现回收站功能脚本

    #!/bin/bash function z-trash() { # 判断参数是否为空 if [ ! $1 ] then echo "z-trash error: file name of ...

  8. 剑指offer54:字符流中第一个不重复的字符

    1 题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中 ...

  9. str.format() 格式化数字的多种方法

    Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能. 基本语法是通过 {} 和 : 来代替以前的 % . format 函数可以接受不限个参数 ...

  10. Tomcat一闪而过的调试方法

    很少用tomcat来部署,都是用springboot微服务.只是以前学的时候搞demo试过而已. 软件测试的期末作业要求要测一个Javaweb的项目,给了一个包然后要求部署在tomcat中并启动. 然 ...