我正在练习编写 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()
在这个修改后的代码中:
-
我们使用
@classmethod
装饰器来标记setUpClass
和tearDownClass
方法,表示它们是类方法而不是实例方法。 -
在
setUpClass
中,我们初始化 WebDriver,并将其存储在类属性cls.driver
中,这样所有测试方法都可以访问它。 -
在
tearDownClass
中,我们关闭 WebDriver,确保在所有测试完成后清理资源。
通过这些修改,你的测试用例将只启动一次浏览器,并在所有测试完成后关闭它,从而避免了为每个测试方法创建新浏览器窗口的问题。
标签:python,unit-testing,selenium-webdriver From: 78828151