<commit_before>---
layout: page
title: Up and Running with Selenium
---

## Design
When you're building out a testing framework, it's important to think about how it's going to be used and who is going to be using it. Here are some things to consider:

  - Tests should be easy to debug
  - Tests should be hermetic
  - Tests should run fast
  - Tests should integrate well with developer workflow
  - Tests should integrate with existing CI/CD Build Systems
  - Tests should be easy to write and maintain

## A basic test suite

One of the libraries I have used for a number of testing projects is [pytest](https://docs.pytest.org/en/latest/). It is the foundation of many testing frameworks and it offers:

* Fixtures (setup and teardown)
* No boilerplate, no required api
* Test collection and discovery
* xUnit report output

## Installation
First, let's install the dependencies below. You can use a
[virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/)
(preferred), but you can also install the packages system-wide.

* `pytest`
* `selenium`
* `simplejson`

## Setup

Now, fire up your favorite text editor, and let's create an base test case with fixtures we can use for all test cases:

    :::python
    from selenium import webdriver

    class SeleniumBaseTestCase(object):

        def setup(self):
            self.driver = webdriver.Firefox()
            self.driver.implicitly_wait(10)

        def teardown(self):
            self.driver.quit()

Fixtures are wrappers around tests that are run before and after the test. In the above example, we startup a new firefox browser for each test and quit the browser when the test has finished. Even if the test fails, the teardown method will still be called.

## Writing your test


## Page Object Model
Page Object Model - A page object model allows you to maintain selectors and page actions in one place rather than individual tests.

### Selectors

The most difficult element of testing is writing robust selectors. Brittle selectors can break whenever slight
changes occur in the DOM. Selectors should be:

* Unique
* Descriptive
* Short

CSS selectors are preferred over XPath. They are faster (especially in IE) and more readable. Here's a
[blog post and video](http://sauceio.com/index.php/2011/05/why-css-locators-are-the-way-to-go-vs-xpath/) from
Santi of Sauce Labs about the advantages of CSS selectors. Not covered in Santi's post is the javascript-xpath
library, which should yield significantly better XPath performance.
This tip came from Dr. <NAME>. You should be able to find his presentation with details on javascript-xpath
at his [Meetup event page](http://www.meetup.com/seleniumsanfrancisco/events/101087592/).

Here's a quick guide to targeting elements using `find_element_by_css_selector()`:

Target | Selector example
--- |:---
Tag | div
Direct child | table > tr
Child or subchild | table td
Id | #my_id
Class | .myclass
Attribute | [name=my_name]
Chained Locators | a.my_class#my_id[name=my_name]

And here's a [comparison of CSS and XPath syntax](http://ejohn.org/blog/xpath-css-selectors/) from <NAME>.
Targeting sibling or parent elements are two situations where you cannot use CSS and need to use XPath.

### Sauce Labs

Sauce Labs allows you to run your tests in the cloud on
[over 150 platform/browser combinations](https://saucelabs.com/docs/platforms).

To use Sauce Labs, we just need to modify our setup fixture to create a remote webdriver instead of the Firefox
one we were using previously. Let's modify our module and test level fixtures:

    :::python
    ...
<commit_msg>update post<commit_after>---
layout: page
title: Up and Running with Selenium
---

# Up and Running with Selenium

## Design
When you're building out a testing framework, it's important to think about how it's going to be used and who is going to be using it. Here are some things to consider:

  - Tests should be easy to debug
  - Tests should be hermetic
  - Tests should run fast
  - Tests should integrate well with developer workflow
  - Tests should integrate with existing CI/CD Build Systems
  - Tests should be easy to write and maintain

## A basic test suite

One of the libraries I have used for a number of testing projects is [pytest](https://docs.pytest.org/en/latest/). It is the foundation of many testing frameworks and it offers:

* Fixtures (setup and teardown)
* No boilerplate, no required api
* Test collection and discovery
* xUnit report output

## Installation
First, let's install the dependencies below. You can use a
[virtualenv](http://docs.python-guide.org/en/latest/dev/virtualenvs/)
(preferred), but you can also install the packages system-wide.

* `pytest`
* `selenium`
* `simplejson`

## Setup

Now, fire up your favorite text editor, and let's create an base test case with fixtures we can use for all test cases:

    :::python
    from selenium import webdriver

    class SeleniumBaseTestCase(object):

        def setup(self):
            self.driver = webdriver.Firefox()
            self.driver.implicitly_wait(10)

        def teardown(self):
            self.driver.quit()

Fixtures are wrappers around tests that are run before and after the test. In the above example, we startup a new firefox browser for each test and quit the browser when the test has finished. Even if the test fails, the teardown method will still be called.

## Writing your test


## Page Object Model
Page Object Model - A page object model is a design pattern which allows you to maintain selectors and page actions in one place rather than individual tests. Its main purpose is to enhance test maintenance and reducing code duplication.

### Selectors

The most difficult element of testing is writing robust selectors. Brittle selectors can break whenever slight changes occur in the DOM. Selectors should be:

* Unique
* Descriptive
* Short

CSS selectors are preferred over XPath. They are faster (especially in IE) and more readable. Here's a [blog post and video](http://sauceio.com/index.php/2011/05/why-css-locators-are-the-way-to-go-vs-xpath/) from Santi of Sauce Labs about the advantages of CSS selectors. Not covered in Santi's post is the javascript-xpath
library, which should yield significantly better XPath performance. This tip came from Dr. <NAME>. You should be able to find his presentation with details on javascript-xpath
at his [Meetup event page](http://www.meetup.com/seleniumsanfrancisco/events/101087592/).

And here's a [comparison of CSS and XPath syntax](http://ejohn.org/blog/xpath-css-selectors/) from <NAME>.
Targeting sibling or parent elements are two situations where you cannot use CSS and need to use XPath.

### Sauce Labs

Sauce Labs allows you to run your tests in the cloud on
[over 150 platform/browser combinations](https://saucelabs.com/docs/platforms).

To use Sauce Labs, we just need to modify our setup fixture to create a remote webdriver instead of the Firefox
one we were using previously. Let's modify our module and test level fixtures:

    :::python
    ...

{'fraction_non_alphanumeric': 0.07007818052594172, 'fraction_numerical': 0.005685856432125089, 'mean_word_length': 3.8457300275482096, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6979854', 'n_tokens_mistral': 1985, 'n_tokens_neox': 1859, 'n_words': 945}