Getting Started with Selenium in Django

This is a quick and dirty guide to get you going ASAP.

Learn How to Use Your Browser’s Debugger/Code Inspector

You should already know how to do this. But if not, testing with Selenium would be painfully difficult. Each browser is different. On Chromium, I right-click on the page to pop up the code inspector.

Use Django’s StaticLiveServerTestCase

This will load all your static files. One important reason to do testing with Selenium is it allows you to test your javascript. It’s also easier to see errors when the page is properly formatted. It’s also a lot easier to spot page errors when the page is properly formatted.

Pausing Selenium

One of the great things about live testing, is you can see what’s going on the the browser, just like your users do. Pausing Selenium and using your browser code inspector is a great way to confirm everything is working or figure out why there are errors.

My preferred way to pause is with:


raw_input('Press any key to continue')

Another approach is to use the python sleep function. I prefer the raw_input method because I often step away from my computer when tests are running. The disadvantage of raw_input is you need to remember to remove it when the test code is completed.

Put IDs in Lots of Your HTML tags

Selenium has a function called “find_element_by_id”. This makes is easy to get and inspect any element on the page that has an ID.  Sure, you could probably get the element using some sort of CSS selector-foo and “find_element_by_css_selector” but why go through the headache.

For example, I am testing a page the has a table of model instances. I just add an ID attribute to my table rows in my Django template:

{% for job in jobs %}
    <tr id="id_{{ job.id }}_row">
        <td>{{ job.name }}</td>
        <td>{{ job.start }}</td>
    </tr>
{% endfor %}

now I can easily see if a certain record is in the table.

Use CSS Class to Get Lists of Elements

Another powerful Selenium method to get a list of elements is “find_elements_by_css_selector”. Look closely at that method name. You will see that it contains “elements” not “element”. Many of the Selenium find methods have a “find_element_by_xxx” and a “find_elements_by_xxx”.

You could get all job start times by adding a class to that <td> tag. Like this:

{% for job in jobs %}
    <tr >
        <td>{{ job.name }}</td>
        <td class="job_start">{{ job.start }}</td>
    </tr>
{% endfor %}

Then in your python code use:


start_times = driver.find_elements_by_css_selector('.job_start')

The “find by CSS selector” functions are pretty powerful in general. For example, if your table has the ID “id_my_table”, you could get all the rows in that table using a CSS descendant selector like this:


start_times = driver.find_elements_by_css_selector('#id_my_table tr')

Checking to See If an Element is on the Page

from selenium.common.exceptions import NoSuchElementException

try:
    the_element = self.selenium.find_element_by_id(element_id)
except NoSuchElementException:
    the_element = None

HTML Select Widgets

Easy once you discover the Selenium Select class. Frequently I use the jQuery Chosen widget with my selects. Working with Chosen in Selenium is a pain. However, in my quest to reduce suffering in the world, I have created a GitHub Gist with all the tricks I have learned. Where ever possible, I used the same method names and signatures as the Selenium Select class.

Debugging HTTP 500 Errors

By default, StaticLiveServerTestCase sets DEBUG=False before running. The reason for this is to make your tests as much like your production environment as possible. The downside is you will not get tracebacks when the server cashes. To get around this problem us the override_settings decorator to set DEBUG = True.

[Errno 98] Address already in use

To clear the address, get the PID using lsof

sudo lsof -i :8081
kill -9 THE_PID

That should get you started. Happy testing.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s