首页 > 编程问答 >有没有办法阻止 setUp() 为 python 测试用例中的每个测试方法启动浏览器?

有没有办法阻止 setUp() 为 python 测试用例中的每个测试方法启动浏览器?

时间:2024-08-03 16:06:20浏览次数:16  
标签:python unit-testing selenium-webdriver

我正在练习编写 Web 自动化测试用例,并且编写了一些函数来测试登录、在用户主页中查找我的用户名以及测试 GitHub 的注销功能。然而,我通过经验和阅读了解到 setUp() 是在每个测试方法之前启动的,而我的问题是在每个测试方法之前它都会打开一个新的浏览器。我希望我的所有测试方法在同一会话中的同一浏览器上继续进行测试。

这是我的代码,向您展示我所尝试的内容:

import unittest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import element_to_be_clickable

class GitHubLoginTest(unittest.TestCase):
    initialized = 0
    completed = 0

    def setUp(self):
        if self.initialized < 1:
            self.initialized = 1
            chrome_options = Options()
            chrome_options.add_experimental_option("detach", True)
            self.driver = webdriver.Chrome(options=chrome_options)
        else:
            pass

    def test_login(self):
        driver = self.driver
        driver.get("https://github.com")
        driver.find_element(By.LINK_TEXT, "Sign in").click()
        username_box = WebDriverWait(driver, 10).until(element_to_be_clickable((By.ID, "login_field")))
        username_box.send_keys("[email protected]")
        password_box = driver.find_element(By.NAME, "password")
        password_box.send_keys("onefaithmanymembers")
        password_box.submit()
        self.completed += 1
        print(self.completed)
        print(self.initialized)

    def test_username_presence(self):
        print(self.completed)
        print(self.initialized)
        self.assertIn("SubjectofthePotentate", self.driver.page_source)
        self.driver.find_element(By.CLASS_NAME, "AppHeader-user").click()
        profile_label = self.driver.find_element(By.CLASS_NAME, "lh-condensed")
        user_label = profile_label.get_attribute("innerHTML")
        print(user_label)
        self.assertIn("SubjectofthePotentate", user_label)
        self.completed += 1
            print(self.completed)

    def test_logout(self):
        self.driver.find_element(By.CLASS_NAME, "DialogOverflowWrapper")
        self.driver.find_element(By.ID, ":r11:").click()
        sign_out = WebDriverWait(self.driver, 10).until(element_to_be_clickable((By.NAME, "commit")))
        sign_out.click()
        self.completed += 1
        print(self.completed)

    def tearDown(self):
        if self.completed == 3:
            self.driver.close()
        else:
            pass

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

我尝试创建我称为 initialization 和||的属性|防止 completed 加载另一个浏览器,也防止 setUp() 在所有测试完成之前关闭浏览器,但会打开一个新浏览器三次,每个测试功能一个。 tearDown() 我注意到,当

print(self.completed) print(self.initialized) 方法中执行时都等于1,但在测试方法 test_login(self) 中再次执行 print(self.completed) print(self.initialized) 时, test_username_presence(self) 等于0且| || 等于 1,所以我认为这意味着 self.completed 方法在每个测试方法之前执行,并且我在类级别定义的属性由于某种原因被重置。我尝试过使用 self.initialized 初始化这些属性,我也尝试过这个: setUp(self) 但我得到了相同的结果,多个浏览器,最后两个是没有URL的空网页。有人知道如何在一个会话中继续在一个浏览器上进行测试吗? setUpClass(cls) and I also tried this:

def __init__(self, other):
    super().__init__(other)
    self.completed = 0
    self.initialized = 0

But I got the same results, multiple browsers and the last two are empty webpages with no URL. Anyone know how I can continue the tests on one browser in one session?


你遇到的问题是,在 Python 的 unittest 框架中,每个测试方法(以 test_ 开头的方法)都会创建一个新的测试用例实例。这意味着你的 initialized completed 属性在每个测试方法开始时都会被重置,因为它们是被绑定到每个测试用例实例上的。

要解决这个问题,你需要使用 setUpClass tearDownClass 方法,这两个方法会在整个测试类中只运行一次。

以下是修改后的代码:

import unittest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import element_to_be_clickable

class GitHubLoginTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        chrome_options = Options()
        chrome_options.add_experimental_option("detach", True)
        cls.driver = webdriver.Chrome(options=chrome_options)

    def test_login(self):
        driver = self.driver
        driver.get("https://github.com")
        driver.find_element(By.LINK_TEXT, "Sign in").click()
        username_box = WebDriverWait(driver, 10).until(element_to_be_clickable((By.ID, "login_field")))
        username_box.send_keys("[email protected]")
        password_box = driver.find_element(By.NAME, "password")
        password_box.send_keys("onefaithmanymembers")
        password_box.submit()

    def test_username_presence(self):
        self.assertIn("SubjectofthePotentate", self.driver.page_source)
        self.driver.find_element(By.CLASS_NAME, "AppHeader-user").click()
        profile_label = self.driver.find_element(By.CLASS_NAME, "lh-condensed")
        user_label = profile_label.get_attribute("innerHTML")
        self.assertIn("SubjectofthePotentate", user_label)

    def test_logout(self):
        self.driver.find_element(By.CLASS_NAME, "DialogOverflowWrapper")
        self.driver.find_element(By.ID, ":r11:").click()
        sign_out = WebDriverWait(self.driver, 10).until(element_to_be_clickable((By.NAME, "commit")))
        sign_out.click()

    @classmethod
    def tearDownClass(cls):
        cls.driver.close()

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

在这个修改后的代码中:

  1. 我们使用 @classmethod 装饰器来标记 setUpClass tearDownClass 方法,表示它们是类方法而不是实例方法。
  2. setUpClass 中,我们初始化 WebDriver,并将其存储在类属性 cls.driver 中,这样所有测试方法都可以访问它。
  3. tearDownClass 中,我们关闭 WebDriver,确保在所有测试完成后清理资源。

通过这些修改,你的测试用例将只启动一次浏览器,并在所有测试完成后关闭它,从而避免了为每个测试方法创建新浏览器窗口的问题。

标签:python,unit-testing,selenium-webdriver
From: 78828151

相关文章

  • 尝试使用Python抓取需要先登录的网站但没有成功
    我正在尝试抓取一个需要登录的网站(我的路由器GUI),但无论我做了什么,我都会反复返回登录站点的源代码,而不是成功登录后出现的页面。我做了一些阅读,并意识到我需要返回POST请求的答案。我想我找到了它们并返回了所需的值,但仍然-似乎没有任何效果。我使用https://curl.tri......
  • 给python初学者的一些建议
    写在开篇关于Python,可以这么说,这几年借着数据科学、机器学习与人工智能的东风,Python老树开新花,在风口浪尖上居高不下。Python之所以这么受大家的青睐,是因为它语言简洁,上手容易,让非计算机专业的人员也能快速上手,享受编程开发带来的便利和福利。但Python再简单,它也是一......
  • Python中15个递归函数经典案例解析
    1.阶乘计算阶乘是一个常见的递归应用,定义为n!=n*(n-1)*…*1。deffactorial(n):ifn==0:return1else:returnn*factorial(n-1)print(factorial(5))#输出:1202.斐波那契数列斐波那契数列的每一项都......
  • 如何使用 python (使用服务帐户)在应用程序脚本 Web 应用程序上触发 doGet()?
    我想从返回json的应用程序脚本Web应用程序触发doGet(e)事件。我们的网络应用程序无法在我们的组织域之外访问,因此需要服务帐户。我执行了下面的代码,但“发生错误:401客户端错误”fromgoogle.oauth2importservice_accountfromgoogle.auth.transport.requestsimpor......
  • 如何使用 BeautifulSoup python 查找选择标签的选定选项值
    我正在尝试从python中的htmlselect标签获取选定的值。好吧,当选项属性设置为selected="selected"时,它是成功的,但我试图废弃的网站具有不同的选项属性,例如:-html="""<select><optionvalue="">Pleaseselectavlalue</option><o......
  • 12:Python元组属性
    #元组tuple,元素不可被修改,不能被增加或则删除tu=(111,'alex',(11,22),[(33,44)],True,33,44,)#一般写元组的时候,最后可以加个逗号不报错print(tu)tu=(111,'alex',(11,22),[(33,44)],True,33,44,)v=tu[0]#元组索引print(v)tu=(111,'alex',(11,2......
  • 如何在venv python中安装requirements.txt
    我是Python虚拟环境的初学者,在安装requirements.txt文件时遇到问题。问题是,当我运行命令来安装requirements.txt文件时,没有安装任何内容。平台:WindowsVS代码镜像如何解决这个问题?没有正确激活虚拟环境。请按照以下步骤操作:1.激活虚拟环境:在VSC......
  • 【代码随想录】图论复习(Python版)
    深度优先搜索1.搜索过程一个方向搜,不到黄河不回头,直到遇到绝境了,搜不下去了,再换方向(换方向的过程就涉及到了回溯)2.代码框架回溯法的代码框架:defbacktracking(参数):if终止条件:存放结果returnfor选择本层集合中的元素(树中节点孩子的数量......
  • 【Python】数据类型之字符串
    本篇文章将继续讲解字符串其他功能:1、求字符串长度功能:len(str)  ,该功能是求字符串str的长度。代码演示:2、通过索引获取字符串的字符。功能:str[a]  str为字符串,a为整型。该功能是获取字符串str索引为a处的字符。注意:字符串的索引是从0开始的。代码演示:注意......
  • 【Python】python基础
    本篇文章将讲解以下知识点:(1)循环语句(2)字符串格式化(3)运算符一:循环语句循环语句有两种:while   for本篇文章只讲解while循环格式:while 条件:  代码(只有条件为真的时候,此代码才会被执行,此处的代码可以是多行代码)(1)循环语句基本使用示例1:此处代码执行过程:1<3......