I've been teaching myself Pytest (using Selenium web driver). All my test functions were in a single file,
test_web.py:
import time
import pytest
from selenium import webdriver
from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.support.ui import WebDriverWait, Select
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class Tags:
starSysButton = '//li[button][1]'
addStarButton = "//button[contains(text(), 'Add Star')]"
starNameField = "//input[1]"
modalAddButton = f"(//button[contains(text(), 'Add')])[2]"
starPath = f"//td[contains(text(),'Bob')]"
planetButton = '//li[button][2]'
addPlanetButton = "//button[contains(text(), 'Add Planet')]"
planetNameField = f"(//input)[1]"
starDropdown = "//select[@placeholder='--Select Star--']"
positionField = f"(//input)[2]"
radiusField = f"(//input)[3]"
gravityField = f"(//input)[4]"
planetPath = f"//td[contains(text(),'Alice')]"
modalClose = "//button[@class='btn-close']"
editPlanetButton = f"(//button[contains(text(), 'Edit')])[4]"
modalUpdateButton = "//button[contains(text(), 'Update')]"
editResultPath = f"//td[contains(text(),'Bob 2')]"
planetDeleteButton = "(//button[contains(text(), 'Delete')])[4]"
starDeleteButton = "(//button[contains(text(), 'Delete')])[5]"
@pytest.fixture
def browser():
driver = Firefox()
driver.implicitly_wait(10)
yield driver
driver.quit()
def test_addStar(browser):
URL = 'http://localhost:4200'
browser.get(URL)
starElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starSysButton)))
starElement.click()
newStarElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.addStarButton)))
newStarElement.click()
enterStarName = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starNameField)))
enterStarName.send_keys("Bob")
clickAddButton = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalAddButton)))
clickAddButton.click()
WebDriverWait(browser, 5).until(EC.alert_is_present())
alert = Alert(browser)
alert.accept()
closeModal = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalClose)))
closeModal.click()
results = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.starPath)))
if results:
assert results
def test_addPlanet(browser):
URL = 'http://localhost:4200'
browser.get(URL)
planetElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.planetButton)))
planetElement.click()
newStarElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.addPlanetButton)))
newStarElement.click()
enterStarName = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.planetNameField)))
enterStarName.send_keys("Alice")
star_select = Select(browser.find_element_by_xpath(Tags.starDropdown))
star_select.select_by_visible_text('Bob')
enterSysPosition = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.positionField)))
enterSysPosition.send_keys("Bob 1")
enterRadius = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.radiusField)))
enterRadius.clear()
enterRadius.send_keys("5432.10")
enterGravity = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.gravityField)))
enterGravity.clear()
enterGravity.send_keys("45.00")
clickAddButton = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalAddButton)))
clickAddButton.click()
browser.implicitly_wait(5)
alert = Alert(browser)
alert.accept()
close_modal = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalClose)))
close_modal.click()
results = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.planetPath)))
if results:
assert results
def test_editPlanet(browser):
URL = 'http://localhost:4200'
browser.get(URL)
planetElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.planetButton)))
planetElement.click()
editPlanet = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.editPlanetButton)))
editPlanet.click()
enterSysPosition = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.positionField)))
enterSysPosition.clear()
enterSysPosition.send_keys("Bob 2")
clickUpdateButton = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalUpdateButton)))
clickUpdateButton.click()
browser.implicitly_wait(5)
alert = Alert(browser)
alert.accept()
close_modal = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalClose)))
close_modal.click()
results = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.editResultPath)))
if results:
assert results
def test_deletePlanet(browser):
URL = 'http://localhost:4200'
browser.get(URL)
planetElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.planetButton)))
planetElement.click()
deletePlanet = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.planetDeleteButton)))
deletePlanet.click()
browser.implicitly_wait(5)
alertOne = Alert(browser)
alertOne.accept()
time.sleep(2)
alertTwo = Alert(browser)
alertTwo.accept()
results = WebDriverWait(browser, 10).until(EC.invisibility_of_element_located((By.XPATH, Tags.planetPath)))
if results:
assert results
def test_deleteStar(browser):
URL = 'http://localhost:4200'
browser.get(URL)
starElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starSysButton)))
starElement.click()
deleteStar = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starDeleteButton)))
deleteStar.click()
browser.implicitly_wait(5)
alertOne = Alert(browser)
alertOne.accept()
time.sleep(2)
alertTwo = Alert(browser)
alertTwo.accept()
results = WebDriverWait(browser, 10).until(EC.invisibility_of_element_located((By.XPATH, Tags.starPath)))
if results:
assert results
I then took each function and placed it in its own class in its own file.
test_addStar was moved to TestCase_AddStar.py and placed inside a class of the same name:
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class Tags:
starSysButton = '//li[button][1]'
addStarButton = "//button[contains(text(), 'Add Star')]"
starNameField = "//input[1]"
modalAddButton = f"(//button[contains(text(), 'Add')])[2]"
starPath = f"//td[contains(text(),'Bob')]"
modalClose = "//button[@class='btn-close']"
class TestCase_AddStar():
URL = 'http://localhost:4200'
def __init__(self, browser):
self.browser = browser
def load(self):
self.browser(self.URL)
def test_addStar(self, browser):
starElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starSysButton)))
starElement.click()
newStarElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.addStarButton)))
newStarElement.click()
enterStarName = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starNameField)))
enterStarName.send_keys("Bob")
clickAddButton = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalAddButton)))
clickAddButton.click()
WebDriverWait(browser, 5).until(EC.alert_is_present())
alert = Alert(browser)
alert.accept()
closeModal = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalClose)))
closeModal.click()
results = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.starPath)))
if results:
assert results
Each TestCase was moved into another directory called TestCases while the driver,
test_web.py, remains in a directory named
tests.
Right now, the driver looks like this:
import pytest
from TestCases.TestCase_AddStar import TestCase_AddStar
from selenium.webdriver import Firefox
@pytest.fixture
def browser():
driver = Firefox()
driver.implicitly_wait(10)
yield driver
driver.quit()
def basic_test(browser):
add_star = TestCase_AddStar(browser)
add_star.load()
Every time I try to run the test, I get the following collection warning:
PytestCollectionWarning: cannot collect test class 'TestCase_AddStar' because it has a __init__ constructor (from: tests/test_web.py)
class TestCase_AddStar():
-- Docs: https://docs.pytest.org/en/stable/warnings.html
What I have tried:
I've tried adding "__test__ = False" to the TestCase code but it just gets skipped when I called the test. I've tried renaming the file so that it doesn't contain the word "test" in it. I've tried to do away with the init constructor, but nothing works.
FIXED
Add a derived fixture to each file containing a test case. The line "browser.get()" will load the Web page and eliminate the need for a load() function.
class TestCase_AddStar():
URL = 'http://localhost:4200'
@pytest.fixture
def load_browser(self, browser):
browser.get(self.URL)
yield browser
def test_addStar(self, load_browser):