Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping Firefox profile persistent in multiple Selenium tests without specifying a profile

Trying to achieve:

  • same firefox profile throughout tests

Problem:

  • Tests are spread over 30 different files, instantiating a selenium object, and thus creating a firefox profile, in the first test won't persist to the following test because the objects die once script ends IIRC

  • Can't specify profile because I'm writing a test suite supposed to be run on different machines

Possible solutions:

  • Creating a selenium object in some common code that stays in memory throughout the tests. I am running each test by spawning a new python process and waiting for it to end. I am unsure how to send objects in memory to a new python object.

Any help is appreciated, thanks.

edit: just thought of instead of spawning a child python process to run the test, I just instantiate the test class that selenium IDE generated, removing the setUp and tearDown methods in all 30 tests, instantiating one selenium object in the beginning, then passing said selenium object to every test that's instantiated.

like image 499
tipu Avatar asked Feb 14 '11 00:02

tipu


1 Answers

I ran into this same problem and also noticed that persisting a single Firefox session across tests sped up the performance of the test suite considerably.

What I did was to create a base class for my Selenium tests that would only activate Firefox if it wasn't already started. During tear-down, this class does not close Firefox. Then, I created a test suite in a separate file that imports all my tests. When I want to run all my tests together, I only execute the test suite. At the end of the test suite, Firefox closes automatically.

Here's the code for the base test class:

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)

This is the test suite:

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())

One disadvantage of this is that if you just run a single test from the command line, Firefox won't automatically close. I typically run all my tests together as part of pushing my code to Github, however, so it hasn't been a big priority for me to fix this.

Here's an example of a single test that works in this system:

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", "[email protected]")
        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()
like image 92
mpdaugherty Avatar answered Oct 28 '22 23:10

mpdaugherty