在多个Selenium测试中保持Firefox配置文件持久化而不指定配置文件

6 投票
2 回答
1770 浏览
提问于 2025-04-16 11:46

想要实现的目标:

  • 在所有测试中使用相同的Firefox用户配置文件

问题:

  • 我的测试分散在30个不同的文件中。在第一个测试中创建的selenium对象(也就是Firefox用户配置文件)在后续测试中无法继续使用,因为一旦脚本结束,这些对象就会消失。

  • 我不能指定用户配置文件,因为我正在编写一个测试套件,计划在不同的机器上运行。

可能的解决方案:

  • 在一些公共代码中创建一个selenium对象,这样它在所有测试中都能保持在内存中。我是通过启动一个新的Python进程来运行每个测试,并等待它结束。我不太确定如何将内存中的对象传递给新的Python对象。

任何帮助都非常感谢,谢谢。

编辑:我刚想到,不用启动一个子Python进程来运行测试,而是直接实例化selenium IDE生成的测试类,去掉所有30个测试中的setUp和tearDown方法,先在开始时实例化一个selenium对象,然后将这个对象传递给每个实例化的测试。

2 个回答

0

你可以在运行服务器的时候指定Firefox的配置文件。这个命令看起来像这样:

java -jar selenium-server.jar -firefoxProfileTemplate "C:\Selenium\Profiles",其中"C:\Selenium\Profiles"是你存放Firefox模板文件的路径。

2

我遇到过同样的问题,还发现如果在测试之间保持一个Firefox的会话不变,测试的速度会快很多。

我做的事情是创建一个基础类,用于我的Selenium测试,这个类只会在Firefox没有启动的时候才激活Firefox。在测试结束时,这个类不会关闭Firefox。然后,我在一个单独的文件中创建了一个测试套件,导入了我所有的测试。当我想要一起运行所有测试时,只需执行这个测试套件。测试套件结束时,Firefox会自动关闭。

这是基础测试类的代码:

from selenium.selenium import selenium
import unittest, time, re
import BRConfig

class BRTestCase(unittest.TestCase):
    selenium = None

    @classmethod
    def getSelenium(cls):
        if (None == cls.selenium):
            cls.selenium = selenium("localhost", 4444, "*chrome", BRConfig.WEBROOT)
            cls.selenium.start()
        return cls.selenium

    @classmethod
    def restartSelenium(cls):
        cls.selenium.stop()
        cls.selenium.start()

    @classmethod
    def stopSelenium(cls):
        cls.selenium.stop()

    def setUp(self):
        self.verificationErrors = []
        self.selenium = BRTestCase.getSelenium()

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

这是测试套件:

import unittest, sys
import BRConfig, BRTestCase

# The following imports are my test cases
import exception_on_signup
import timezone_error_on_checkout
import ...

def suite():
    return unittest.TestSuite((\
        unittest.makeSuite(exception_on_signup.ExceptionOnSignup),
        unittest.makeSuite(timezone_error_on_checkout.TimezoneErrorOnCheckout),
        ...
    ))

if __name__ == "__main__":
    result = unittest.TextTestRunner(verbosity=2).run(suite())
    BRTestCase.BRTestCase.stopSelenium()
    sys.exit(not result.wasSuccessful())

这样做的一个缺点是,如果你只是从命令行运行一个单独的测试,Firefox不会自动关闭。不过我通常会把所有测试一起运行,作为我把代码推送到Github的一部分,所以这个问题对我来说并不是特别紧急。

这是一个在这个系统中工作的单个测试示例:

from selenium.selenium import selenium
import unittest, time, re
import BRConfig
from BRTestCase import BRTestCase

class Signin(BRTestCase):
    def test_signin(self):
        sel = self.selenium
        sel.open("/signout")
        sel.open("/")
        sel.open("signin")
        sel.type("email", "test@test.com")
        sel.type("password", "test")
        sel.click("//div[@id='signInControl']/form/input[@type='submit']")
        sel.wait_for_page_to_load("30000")
        self.assertEqual(BRConfig.WEBROOT, sel.get_location())

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

撰写回答