selenium with py test by alexandr vasyliev for lohika odessa python techtalks
TRANSCRIPT
Alexander Vasilyev
Selenium+py.test
• Selenium overwiew• Some Samples• Actions• Fixtures• Travis CI • Jenkins CI
Agenda
Parts of Selenium:
•Selenium Webdriver (Selenium 2)•Selenium IDE•Selenium Server•Selenium-Grid
Selenium Overview
• Google Chrome• Internet Explorer 6, 7, 8, 9, 10 - 32 and 64-bit where applicable• Firefox: latest ESR, previous ESR, current release, one previous
release• Safari• Opera• HtmlUnit• phantomjs• Android (with Selendroid or appium)• iOS (with ios-driver or appium)
Selenium Overview
Selenium Overview
• find_element_by_id• find_element_by_name• find_element_by_xpath• find_element_by_link_text• find_element_by_partial_link_text• find_element_by_tag_name• find_element_by_class_name• find_element_by_css_selector
Find & Interact
def login_field(self): return self.wait.until(EC.element_to_be_clickable((By.NAME, 'Login')))
def password_field(self): return self.wait.until(EC.element_to_be_clickable((By.NAME, 'Password')))
def login_button(self): return self.wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@type='submit']")))
def error_message(self): return self.wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='error-text']")))
def login_username(self): return self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "username")))
def logout_button(self): return self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "logout")))
Find
Interact
def login(self, name, password): self.login_field().send_keys(name) self.password_field().send_keys(password) self.login_button().click()
Actions
actions = ActionChains(driver)test_plan = wait.until(EC.presence_of_element_located((By.XPATH, ".//ul/li[1]")))actions.move_to_element(test_plan)actions.click(test_plan)actions.perform()
Asserts
Asserts•assertEqual(a, b) •assertNotEqual(a, b) •assertTrue(x) •assertFalse(x)
error_message = self.wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='error-text']")))unittest.TestCase.assertEqual(error_message.is_displayed(), True, "Should return error-message")
All togetherimport pageObjects.login_pageimport unittestfrom selenium import webdriverfrom selenium.webdriver.common.keys import Keys
class TestClass(unittest.TestCase):
def setUp(self): self.driver = webdriver.Firefox() self.wait = WebDriverWait(self.driver, 10)
def tearDown(self): self.driver.quit() pass
def test_input_field(self): self.driver.get("http://www.ukr.net") login_page.login("name", "pasword") unittest.TestCase.assertEqual(login_page.error_message().is_displayed(), True, "Should return error-message")
if __name__ == '__main__': unittest.main()
setUp&tearDown
def setUp(self): self.driver = webdriver.Firefox() self.wait = WebDriverWait(self.driver, 10)
def tearDown(self): self.driver.quit() pass
py.test
http://pytest.org/
The pytest testing tool makes it easy to write small tests, yet scales to support complex functional testing. It provides
•auto-discovery of test modules and functions,•detailed info on failing assert statements (no need to remember self.assert* names)•fixtures for managing small or parametrized long-lived test resources.•you can use pytest to run test suites based on unittest (or trial), nose•single-source compatibility from Python2.6 all the way up to Python3.4, PyPy-2.3•many external plugins.
py.test test discoverypytest implements the following standard test discovery:
•collection starts from the initial command line arguments which may be directories, filenames or test ids.•recurse into directories, unless they match norecursedirs•test_*.py or *_test.py files, imported by their test package name.•Test prefixed test classes (without an __init__ method)•test_ prefixed test functions or methods are test items
py.test asserts
def test_set_comparison(): set1 = set("1308") set2 = set("8035") assert set1 == set2
py.test asserts
================================= FAILURES =================================___________________________ test_set_comparison ____________________________
def test_set_comparison(): set1 = set("1308") set2 = set("8035")> assert set1 == set2E assert set(['0', '1', '3', '8']) == set(['0', '3', '5', '8'])E Extra items in the left set:E '1'E Extra items in the right set:E '5'E Use -v to get the full diff
test_assert2.py:5: AssertionError========================= 1 failed in 0.01 seconds =========================
py.test asserts
Special comparisons are done for a number of cases:•comparing long strings: a context diff is shown•comparing long sequences: first failing indices•comparing dicts: different entries
py.test fixtures
The purpose of test fixtures is to provide a fixed baseline upon which tests can reliably and repeatedly execute. pytest fixtures offer advantage over the classic xUnit style of setup/teardown functions:•fixtures have explicit names and are activated by declaring their use from test functions, modules, classes or whole projects.•fixtures are implemented in a modular manner, as each fixture name triggers a fixture function which can itself use other fixtures.•fixture management scales from simple unit to complex functional testing, allowing to parametrize fixtures and tests according to configuration and component options, or to re-use fixtures across class, module or whole test session scopes.
py.test fixtures discovery
The discovery of fixtures functions starts at test classes, then test modules, then conftest.py files and finally built-in and third party plugins.
py.test fixtures
@pytest.fixture def driver(): _driver = webdriver.Firefox() def driver_teardown(): _driver.quit() request.addfinalizer(driver_teardown) return _driver
def test_server_connect(driver): driver.get("ukr.net") assert "UKR" in driver.title
py.test fixtures
@pytest.yield_fixturedef driver(): _driver = webdriver.Firefox() yield _driver _driver.quit()
def test_server_connect(driver): driver.get("ukr.net") assert "UKR" in driver.title
py.test parameterize
chrome_driver = webdriver.Remote(selenium_grid_url, desired_capabilities={'platform': 'ANY', 'browserName': 'chrome', 'version': '', 'javascriptEnabled': True})
firefox_driver = webdriver.Remote(selenium_grid_url, desired_capabilities={'platform': 'ANY', 'browserName': 'firefox', 'version': '', 'javascriptEnabled': True})
@pytest.mark.parametrize('driver', [chrome_driver, firefox_driver])def test_login(driver): login_page = LoginPage(driver) driver.get("http://www.ukr.net") login_page.login(login, password) assert login_page.login_username().is_displayed() is True
py.test pytest-xdist
The pytest-xdist plugin extends py.test with some unique test execution modes:
•test run parallelization: if you have multiple CPUs or hosts you can use those for a combined test run. This allows to speed up development or to use special resources of remote machines.•--boxed: (not available on Windows) run each test in a boxed subprocess to survive SEGFAULTS or otherwise dying processes•--looponfail: run your tests repeatedly in a subprocess. After each run py.test waits until a file in your project changes and then re-runs the previously failing tests. This is repeated until all tests pass after which again a full run is performed.•Multi-Platform coverage: you can specify different Python interpreters or different platforms and run tests in parallel on all of them.
py.test pytest-xdist
Localy : py.test -n5 test_ukrnet.py
Distribute: py.test -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg
py.test CI-Travis
Travis CI is a hosted continuous integration service. It is integrated with GitHub.Travis CI's build environment provides different runtimes for different languages, for instance multiple versions of Python, Ruby, PHP, Node.js. It also comes preinstalled with a variety of data stores and common tools like message brokers.
py.test CI-Travis
language: pythonpython: - "2.7"before_install: - "sh -e /etc/init.d/xvfb start" - "export DISPLAY=:99.0" - "wget http://selenium-release.storage.googleapis.com/2.44/selenium-server-standalone-2.44.0.jar" - "java -jar selenium-server-standalone-2.44.0.jar > /dev/null &" - "sleep 10"# command to install dependenciesinstall: - "pip install -r requirements.txt"# command to run testsscript: py.test
py.test SauceLabs
https://docs.saucelabs.com/tutorials/python/
from selenium import webdriver
sauce_url = "http://YOUR_USERNAME:[email protected]:80/wd/hub"
desired_capabilities = { 'platform': "Mac OS X 10.9", 'browserName': "chrome", 'version': "31",}
driver = webdriver.Remote(desired_capabilities=desired_capabilities, command_executor=sauce_url)driver.implicitly_wait(10)
py.test CI-Jenkins
py.test --junitxml=path
py.test CI-Jenkins
Thank You!