【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案...

2023-11-13

 我一直在思考第一个博客应该写什么,然后我就解决了开通博客后解决的第一个问题,择题不如撞题;

  如果大多数人和我一样,接触python+selenium+unittest是从selenium IDE开始的话,你也一定会遇到这样的问题:

  我们写了5个,10个,甚至20个测试用例,放在一个py脚本里,每个测试用例执行完毕之后,都会走一遍退出浏览器的操作,然后再启动浏览器,再退出,如此反复,浪费了大量的时间,今天就说说我研究解决这个问题的历程;

  我们第一个录制并导出的python selenium代码,万能的“登录功能”,是这个样子的:

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re

class Login(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://192.168.1.207:8080"
        self.verificationErrors = []
        self.accept_next_alert = True

    def test_login(self):
        driver = self.driver
        driver.get(self.base_url + "/QAS/RchWebSchool/")
        driver.find_element_by_css_selector("span").click()
        driver.find_element_by_name("j_password").clear()
        driver.find_element_by_name("j_password").send_keys("admin")
        driver.find_element_by_name("j_username").clear()
        driver.find_element_by_name("j_username").send_keys("admin")
        driver.find_element_by_xpath("//button[@type='submit']").click()

    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True

    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True

    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()

  往往我们很容易读懂这三个def(如果读不懂,请看虫师先生的博客:selenium-webdriver(python) (十六) --unittest 框架):

    setUp(self)
    test_login(self)
    tearDown(self)

  读懂之后,我们就可以写另外一个功能“修改个人信息”的自动化脚本了,假设我们在class:Login 里是这样写的:

    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://192.168.1.207:8080"
        self.verificationErrors = []
        self.accept_next_alert = True

    def test_login(self):
        driver = self.driver
        driver.get(self.base_url + "/QAS/RchWebSchool/")
        driver.find_element_by_css_selector("span").click()
        driver.find_element_by_name("j_password").clear()
        driver.find_element_by_name("j_password").send_keys("admin")
        driver.find_element_by_name("j_username").clear()
        driver.find_element_by_name("j_username").send_keys("admin")
        driver.find_element_by_xpath("//button[@type='submit']").click()
    
    def test_login_reg(self):
        driver = self.driver
        driver.get(self.base_url + "/QAS/RchWebSchool/")

        #登录代码
        ...
        #修改个人信息代码
        ...


    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

  我们发现,每增加一个测试用例,都增加一次操作:启动浏览器(setUp)→登录测试网址(#登录代码)→关闭浏览器(teardown),而当用例过多的时候,如此反复的操作会浪费大量的时间;

  怎么办呢?  

  如果我们能只走一次启动浏览器和退出浏览器,那该有多好啊;

  我们尝试将所有的功能的操作都写在一个test里面,我们的test_login(self)代码就变成了这样:

    def test_login(self):
        driver = self.driver
        driver.get(self.base_url + "/QAS/RchWebSchool/")
        driver.find_element_by_css_selector("span").click()
        driver.find_element_by_name("j_password").clear()
        driver.find_element_by_name("j_password").send_keys("admin")
        driver.find_element_by_name("j_username").clear()
        driver.find_element_by_name("j_username").send_keys("admin")
        driver.find_element_by_xpath("//button[@type='submit']").click()
        
        
        #修改个人信息
        ...
        #功能续3
        ...
        #功能续4
        ...

  但是,这样就了一个新的问题,当我们只测试其中一个功能,或者用到其中某一个功能的时候,没有办法单独调用某一个功能的代码,失去了原本的灵活性;

  所以阳阳针对class:Login里的代码进行这样改(请看注释):

 1     dr = webdriver.Firefox()#定义全局的dr,不在setUp函数里,实现了只启动一次firefox
 2     def setUp(self,driver= dr):
 3         self.driver = driver#初始化数据中,将全局变量dr赋值给self.driver,这样每次测试开始都只会锁定dr,而不是新创建一个
 4         self.driver.implicitly_wait(30)
 5         self.base_url = "http://192.168.1.207:8081"
 6         self.verificationErrors = []
 7         self.accept_next_alert = True
 8 
 9     def test_login(self):
10         driver = self.driver
11         driver.get(self.base_url + "/RchWebSchool/")
12         driver.find_element_by_css_selector("span").click()
13         driver.find_element_by_name("j_password").clear()
14         driver.find_element_by_name("j_password").send_keys("admin")
15         driver.find_element_by_name("j_username").clear()
16         driver.find_element_by_name("j_username").send_keys("admin")
17         driver.find_element_by_xpath("//button[@type='submit']").click()
18 
19     def test_login_reg(self):
20         driver = self.driver
21         #driver.get(self.base_url + "/RchWebSchool/")
22         ...
23         #修改个人信息自动化代码
24         ...
25 
26     def test_zzz_quit(self):#最后一个测试用例,实现了只进行一次退出浏览器
27         self.driver.quit()
28 
29 
30     def tearDown(self):
31         try:
32             self.driver.refresh()#将退出浏览器的操作变成刷新浏览器,用于不同用例之间的接洽操作
33         except ConnectionRefusedError as e:
34             print(e)
35         finally:
36             self.assertEqual([], self.verificationErrors)

  大家应该看到,阳阳把tearown(self)里面的代码已经改的面目全非了,这是因为我们每个测试用例(test_xxx)执行之后,都会走一次tearown,最后一个退出浏览器的test_zzz_quit当然也不例外,所以在走完test_zzz_quit之后,一定会再次执行刷新浏览器的操作,但是此前浏览器已经被关闭了,刷新浏览器一定会报错,所以把异常ConnectionRefusedError抛出,不再进行处理,视为测试用例通过;

  当然,如果自动化只到这里的话,大家也可把teardown干掉,把每次刷新浏览器的操作放在每个测试用例的最后面,都是可以的,我只是习惯性保持unittest的完整性;

  

转载于:https://www.cnblogs.com/bainianfengri/p/7251164.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案... 的相关文章

随机推荐

  • 使用反射技术实现的导入Excel文件到数据库的公共方法

    还是干脆 利索直接上代码最实惠 1 定义接口类IImportService public interface IImportService
  • R语言—随机抽样

    文章目录 专题 随机抽样 简单随机抽样 sample函数 srswor函数 srswr函数 分层抽样 专题 随机抽样 简单随机抽样 从总体中抽取样本的方法很多 最常用的方法是简单随机抽样 简单随机抽样 从容量为N的总体中 任意抽取n个单位作
  • consul学习与常用命令和使用教程

    目录 consul是什么 常用命令 API 实例1 新建服务API 注册服务 查询服务 consul是什么 Consul是分布式的 高可用的 可横向扩展的用于实现分布式系统的服务发现与配置 consul就是提供服务发现的工具 做服务发现的框
  • pyqt5按钮点击时传递参数(通过lambda表达式)

    pyqt5中按钮点击事件的响应 常见的是下面的方式 self btn clicked connet self click method 现在想在按钮click的时候能够传递参数 可以借助lambda表达式 self btn clicked
  • 数字IC手撕代码---百题斩

    前言 本篇导览目录 用来索引笔者写的其他手撕代码文章 本专栏旨在记录高频笔面试手撕代码题 以备数字前端秋招 本专栏所有文章提供原理分析 代码及波形 所有代码均经过本人验证 目录如下 1 数字IC手撕代码 分频器 任意偶数分频 2 数字IC手
  • 线性代数的本质(六)——线性空间

    文章目录 线性空间 线性空间 子空间 坐标与同构 线性变换与矩阵 基变换与坐标变换 线性空间 线性空间 Grant 普适的代价是抽象 仔细分析就会发现 关于向量空间的一切概念及有关定理都不依赖于向量的具体表现形式 有序数组 也不依赖于向量加
  • 17、SysTick—系统定时器

    17 SysTick 系统定时器 文章目录 17 SysTick 系统定时器 1 SysTick简介 2 SysTick寄存器介绍 3 SysTick 定时实验 3 1 硬件设计 3 2 软件设计 本章参考资料 Cortex M3 内核编程
  • 【硬件电子】基础知识点学习记录

    眼图 USB信号质量判断通过下面哪个参数来判断 A 眼图 B 电压 C 信噪比 D 失真度 解析 眼图测试主要是用来检测高速串行传输的信号质量 本题选A 眼图 是由于示波器的余辉作用 将扫描所得的每一个码元波形重叠在一起 从而形成眼图 眼图
  • numa节点间CPU利用率不均衡 - wakeup affinity

    最近遇到服务器numa节点间cpu利用率不均衡 清除sched domain的flags中的AFFINE WAKEUPS标志位是一个优化方法 但是如果直接将AFFINE WAKEUPS关闭 将无法充分利用L2 L3 cache缓存命中带来的
  • JMeter软件的安装(超详细教程)

    JMeter软件的安装 超详细教程 1 jdk的安装 1 1jdk的环境变量配置 2 JMeter的安装 1 1JMeter的环境变量配置 3 JMeter的运行 第一个问题 为什么下载JMeter要先下载jdk 因为JMeter是Apac
  • 数据库还原-bak文件

    数据库还原 我知道有俩种方式 一种方式是直接在数据库上操作 一种是在数据库里用代码还原 第一种方法 1 数据库上右击 选择还原文件和文件组 2 选择目标数据库 选择bak文件 确定即可还原数据库 一般情况下这样就可以还原数据库了 但有时会报
  • nginx报错:./configure: error: C compiler cc is not found, gcc 是已经安装了的

    源码安装nginx报错 找不到gcc 但是实际上gcc是存在的 如下 configure checking for OS Linux 3 10 0 957 el7 x86 64 x86 64 checking for C compiler
  • GJB1188A校验C语言算法

    GJB1188A校验和算法 先将2个字节数据拼接为一个字 16字节 然后循环右移 之后模2算法合成 按位异或 就是 运算符 最后再反向移位 循环右移 消息队列中第一个字不移位 第二个右移1位 第三个右移2位 按位异或 相同为0 不同为1 消
  • rk3399 Android9.0 ota升级失败

    rk3399 Android9 0 ota升级失败 问题 在rk3399 Android9 0 项目中需要 ota 功能 user版本编译完ota升级包后 在同版本整包升级时遇到如下问题 抓到的logcat内容如下 1044 2343 D
  • 数据安全风险分析及应对策略研究

    报告从理论与实践层面对当前企业面临的内外部数据安全风险进行分析与研究 完成了以下几方面的探索 一是梳理了当前数据安全面临的突出问题 二是提出了数据安全体系建设的行动思路和关键举措 三是提出了数据安全建设发展建议 关注公众号 互联互通社区 回
  • angular自动化测试--protractor

    前戏 面向模型编程 测试驱动开发 先保障交互逻辑 再调整细节 by 雪狼 为什么要自动化测试 1 提高产出质量 2 减少重构时的痛 反正我最近重构多了 痛苦经历多了 3 便于新人接手 angular自动化测试主要分 端到端测试和单元测试 很
  • 专访戴文渊:第四范式(现在)是一家怎样的公司?

    李根 发自 凹非寺 量子位 报道 公众号 QbitAI 第四范式创始人及CEO戴文渊 第四范式是一家备受关注的公司 仅创始团队成员来看 哪一个不是计算机 机器学习领域响当当的名字 戴文渊是ACM2005全球冠军 百度机器学习系统带队打造者
  • RecyclerView中item布局的"match_parent"属性失效--LayoutInflate的深入了解

    用recyclerview 给item布局使用了match parent属性 运行后不起作用 查了下 是在onCreateViewHolder中加载布局时候出了问题 一开始用的View Inflate方法 查看源码后 发现View infl
  • Java学生个人信息录入

    编写 Java 程序显示学生的个人信息 定义类Student 该类中应该有三个私有属性 姓名 name 年龄 age 性别 sex 输入 第一行为一个数 表示录入学生个数 第二行依次为学生姓名 年龄 性别 最后一行输入一个学生的姓名 输出
  • 【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案...

    我一直在思考第一个博客应该写什么 然后我就解决了开通博客后解决的第一个问题 择题不如撞题 如果大多数人和我一样 接触python selenium unittest是从selenium IDE开始的话 你也一定会遇到这样的问题 我们写了5个