Hello,
I hope the community here could give me some feedback on on my first practice project using pytest and Selenium. The project contains a separate file for the pytest fixture and then two separate tests.
Some notes on my decisions:
I chose not to use page objects mostly because I prioritize visibility, and I prefer that I all code for a test be neatly visible in one file.
My locators are maybe odd. I tried xpath relative paths but I must have done something wrong, so I settled for absolute paths which works just fine. But this kind of locator is far from readable of course. I have more to learn about locators.
I have learned that flakiness is a thing. I have read about flaky tests from tutorials and blogs but now I know what it means. This test fails on my machine every now and then. (Timeouts when another browser is open or element not interactable) It would be easier to deal with a consistent fail rather than one that appears occasionally. I don’t expect anyone to run my test files, but if there is anything in the code that stands out as a likely culprit please let me know.
One line of code is identical in both tests. A constant:
URL = “Home - Oodi”
On one hand I understand repeated code is a code smell, on the other hand the two tests are isolated from one another. Let me know if there is a better way to declare this constant.
All in all I enjoy thinking trough a test case and see Selenium execute it with my own eyes. Working with Selenium seems to be a lot about making deliberate and thoughtful decisions on what to test and why.
Anyhow. If anyone spots a particularly rankling code smell let me know. All feedback is greatly appreciated.
Code below:
conftest.py
import pytest
from selenium.webdriver import Chrome
\# Initialize and quit handled by a pytest fixture
@pytest.fixture
*def* browser(*scope*="module"):
driver = Chrome()
driver.implicitly_wait(15)
yield driver
driver.quit()
test_oodi_FAQS.py
from selenium.webdriver.common.by import By
from selenium.common.exceptions import ElementClickInterceptedException
from selenium.common.exceptions import NoSuchElementException
*def* test_oodi_faq_interaction(*browser*):
\# GIVEN The Oodi homepage is displayed
URL = "https://www.oodihelsinki.fi/en/"
browser.get(URL)
browser.implicitly_wait(20)
\# WHEN the user clicks on FAQ
faq_search_window = browser.find_element(By.LINK_TEXT, "Questions and answers")
browser.implicitly_wait(20)
while True:
try:
faq_search_window.click()
break
except ElementClickInterceptedException:
browser.execute_script("window.scrollBy(0,-100);")
\# THEN the FAQ page is displayed
assert browser.current_url == "https://www.oodihelsinki.fi/en/faq/"
browser.implicitly_wait(20)
\# AND the fact about dogs in the library is displayed
xpath = "/html/body/div[1]/div[1]/div/div/section[2]/div[16]/div/div[1]/h3"
*def* element_present_check():
try:
browser.find_element(By.XPATH, xpath)
return True
except NoSuchElementException:
return False
assert element_present_check() is True
test_oodi_facilities.py
from selenium.webdriver.common.by import By
\# from selenium.common.exceptions import ElementClickInterceptedException
*def* test_oodi_facilities_interaction(*browser*):
\# Given The Oodi homepage is displayed
URL = "https://www.oodihelsinki.fi/en/"
browser.get(URL)
browser.implicitly_wait(20)
\# WHEN the user clicks the plus buttton to expand 'Services and facilities'
\# AND the user clicks on 'facilities'
plus_button_xpath = ("/html/body/section/div[1]/div[1]/nav/ul/li[2]/button/div/div[2]")
facilities_xpath = "/html/body/section/div[1]/div[1]/nav/ul/li[2]/ul/li/ul/li[2]/a"
browser.implicitly_wait(20)
plus_button = browser.find_element(By.XPATH, plus_button_xpath)
plus_button.click()
browser.implicitly_wait(20)
facilities = browser.find_element(By.XPATH, facilities_xpath)
facilities.click()
browser.implicitly_wait(20)
\# THEN the user is on the facilities page
assert (browser.current_url == "https://www.oodihelsinki.fi/en/services-and-facilities/facilities/")