1

I'm having some real issues trying to work out how to get this to work, and I'm sure there are some experts on here who can work it out for me, please :)

So I have a number of test cases in python that all follow on from each other, but are individual scripts, I want to combine these and run them in order, in a single webdriver instance, as they all follow on, but I can't seem to work out how to do it..

I have created a test suite -

import unittest

from Searchfieldreturnscorrectvalue import SearchFieldReturnsCorrectValue

from Navigatetostreetlightprecontentpage import Navigatetostreetlightprecontentpage


class TestSuite(unittest.TestSuite):

  def suite():
    suite = unittest.TestSuite()
suite.addTest(Searchfieldreturnscorrectvalue('test_searchfieldreturnscorrectvalue'))
suite.addTest(Navigatetostreetlightprecontentpage('test_navigatetostreetlightprecontentpage'))
return suite

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

This runs the tests, but the second one fails as it tried to run it in a second firefox instance..

Searchfieldreturnscorrectvalue.py

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 SearchFieldReturnsCorrectValue(unittest.TestCase):
def setUp(self):
    self.driver = webdriver.Firefox()
    self.driver.implicitly_wait(30)
    self.base_url = "https://www.XXXXX.com/"
    self.verificationErrors = []
    self.accept_next_alert = True

def test_search_field_returns_correct_value(self):
    driver = self.driver
    driver.get(self.base_url + "/")
    driver.find_element_by_id("edit-search-block-form--2").click()
    driver.find_element_by_id("edit-query").clear()
    driver.find_element_by_id("edit-query").send_keys("street light")
    driver.find_element_by_id("edit-query").send_keys(Keys.ENTER)
    for i in range(60):
        try:
            if self.is_element_present(By.LINK_TEXT, "Street lighting"): break
        except: pass
        time.sleep(1)
    else: self.fail("time out")
    try: self.assertEqual("Street lighting", driver.find_element_by_link_text("Street lighting").text)
    except AssertionError as e: self.verificationErrors.append(str(e))

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.assertEqual([], self.verificationErrors)

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

Navigatetostreetlightprecontentpage.py

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 Navigatetostreetlightprecontentpage(unittest.TestCase):
def setUp(self):
    self.driver = webdriver.Firefox()
    self.verificationErrors = []
    self.accept_next_alert = True

def test_navigatetostreetlightprecontentpage(self):
    driver = self.driver
    driver.find_element_by_link_text("Street lighting").click()
    try: self.assertEqual("Street lighting", driver.find_element_by_css_selector("h1.page-title__main__title").text)
    except AssertionError as e: self.verificationErrors.append(str(e))
    try: self.assertEqual("Report a faulty street light | Cheshire East", driver.title)
    except AssertionError as e: self.verificationErrors.append(str(e))

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.assertEqual([], self.verificationErrors)

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

I don't know if a test suite is the correct way to do it, or to just get all the tests into one file, but I still would want the "Classes/Tests" to individually report pass/fail, at the moment I can't get that to work, I think it is something to do with the setUp(self) needing to be moved to a setUpModule and shared? But I can't work it out, if someone could please point me in the right direction, I would be very grateful.

Thanks

Update

Example of what I have tired as per comment bellow, still not working..

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 SeleniumTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
    cls.driver = webdriver.Firefox()
    cls.driver.maximize_window()

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

class SearchFieldReturnsCorrectValue(SeleniumTest):
def setUp(cls):
    cls.base_url = "https://www.XXXXX.com"
    cls.verificationErrors = []
    cls.accept_next_alert = True

def test_search_field_returns_correct_value(cls):
    driver = cls.driver
    driver.get(cls.base_url + "/")
    driver.find_element_by_id("edit-search-block-form--2").click()
    driver.find_element_by_id("edit-query").clear()
    driver.find_element_by_id("edit-query").send_keys("street light")
    driver.find_element_by_id("edit-query").send_keys(Keys.ENTER)
    for i in range(60):
        try:
            if cls.is_element_present(By.LINK_TEXT, "Street lighting"): break
        except: pass
        time.sleep(1)
    else: cls.fail("time out")
    try: cls.assertEqual("Street lighting", driver.find_element_by_link_text("Street lighting").text)
    except AssertionError as e: cls.verificationErrors.append(str(e))
    driver.find_element_by_link_text("Street lighting").click()

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

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

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

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


class Navigatetostreetlightprecontentpage(SeleniumTest):
def setUp(cls):
    cls.verificationErrors = []
    cls.accept_next_alert = True

def test_navigatetostreetlightprecontentpage(cls):
    driver = cls.driver
    try: cls.assertEqual("Street lighting", driver.find_element_by_css_selector("h1.page-title__main__title").text)
    except AssertionError as e: cls.verificationErrors.append(str(e))
    try: cls.assertEqual("Report a faulty street light | Cheshire East", driver.title)
    except AssertionError as e: cls.verificationErrors.append(str(e))

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

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

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

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

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

This seems to be running both classes now, but the second class is never able to locate any elements, but the same line in the first class works perfectly.

2 Answers 2

3

I am not sure I understood well, but to use a single driver instance, you can use the setupClass class method where you create the driver:

class MyTestClass(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Firefox()

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

    def setUp(self):
         ....

It will still recreate the driver for every new test class, but it does not recreate one for every test (as setUp does).

Personnally I make all my test classes inherit from a SeleniumTest class like this:

class SeleniumTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Firefox()

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

class MyTestClass(SeleniumTest):
    def setUp(self):
         ....
Sign up to request clarification or add additional context in comments.

9 Comments

I think I understand what you mean, I have tried to combine the 2 together using this now, I will update my original question with what I now have, but it doesn't seem to run the second class/test after completing the first class?
cls.driver.maximize_window() should also go inside setupClass. Apart from that, I don't know why your second class does not run. How do you call the tests? I use pytest and it runs everything fine. Note that setupClass will recreate the driver for every new class, just it does not recreate one for every test (as setUp does).
Maybe you forgot to make the second test class inherit from SeleniumTest, too ?
Ok, thanks I will double check and try again when back in the office, I am using LiClipse with PyDev integrated?
Hey, I have changed some of the code, and it is now running the second class after, the problem is, it can't find any element, No matter what I put in the second class, it can never locate element, but if I move the "find" to the first class, it works straight away, can you think of any reason for that? I will update my edit with the version I have now..thank for your help JulienD
|
0

import unittest

from selenium import webdriver from time import sleep class SeleniumTest(unittest.TestCase):

global driver

@classmethod
def setUpClass(cls):
    #getting a common webdriver instance for all your tests for this module
    cls.driver = webdriver.Chrome("/Users/sibasish/PycharmProjects/CommonDriverInstance/chromedriver")
    cls.driver.get("https://www.google.com")

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

class MyTestClass(SeleniumTest): def setUp(self): pass

def test_sample1(self):
    print("hello1")
    self.driver.get("https://www.google.com/")
    sleep(4)

def test_sample2(self):
    print("hello2")
    self.driver.get("https://www.facebook.com/")
    sleep(4)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.