O'Reilly logo

Test-Driven Development with Python by Harry J.W. Percival

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Appendix A. PythonAnywhere

Are you planning to use PythonAnywhere to follow along with this book? Here’s a few notes on how to get things working, specifically with regards to Selenium/Firefox tests, running the test server, and screenshots.

If you haven’t already, you’ll need to sign up for a PythonAnywhere account. A free one should be fine.

Running Firefox Selenium Sessions with Xvfb

The next thing is that PythonAnywhere is a console-only environment, so it doesn’t have a display in which to pop up Firefox. But we can use a virtual display.

In Chapter 1, when we write our first ever test, you’ll find things don’t work as expected. The first test looks like this, and you can type it in using the PythonAnywhere editor just fine:

from selenium import webdriver
browser = webdriver.Firefox()
assert 'Django' in browser.title

But when you try and run it (in a Bash console), you’ll get an error:

$ python3 functional_tests.py
Traceback (most recent call last):
File "tests.py", line 3, in <module>
browser = webdriver.Firefox()
File "/usr/local/lib/python3.3/site-packages/selenium/webdriver/firefox/webdrive
self.binary, timeout),
File "/usr/local/lib/python3.3/site-packages/selenium/webdriver/firefox/extensio
File "/usr/local/lib/python3.3/site-packages/selenium/webdriver/firefox/firefox_
File "/usr/local/lib/python3.3/site-packages/selenium/webdriver/firefox/firefox_
selenium.common.exceptions.WebDriverException: Message: 'The browser appears to
have exited before we could connect. The output was: Error: no display

The fix is to use Xvfb, which stands for X Virtual Framebuffer. It will start up a “virtual” display, which Firefox can use even though the server doesn’t have a real one.


If, instead, you see "ImportError, no module named selenium“, do a pip3 install --user selenium.

The command xvfb-run will run the next command in Xvfb. Using that will give us our expected failure:

$ xvfb-run python3 functional_tests.py
Traceback (most recent call last):
File "tests.py", line 11, in <module>
assert 'Django' in browser.title

Setting Up Django as a PythonAnywhere Web App

Shortly after that, we set up Django. Rather than using the django-admin.py startproject command, I recommend you use the PythonAnywhere quick-start option in the Web tab. Add a new web app, choose Django, Python 3, and then use superlists as the project name.

Then, instead of running the test server from a console on localhost:8000, you can use the real URL of your PythonAnywhere web app:



You’ll need to remember to hit “Reload Web App” whenever you make changes to the code, to update the site.

That should work better.[37]

Cleaning Up /tmp

Selenium and Xvfb tend to leave a lot of junk lying around in /tmp, especially when they’re not shut down tidily (that’s why I included a try/finally earlier).

In fact they leave so much stuff lying around that they might max out your storage quota. So do a tidy-up in /tmp every so often:

$ rm -rf /tmp/*


In Chapter 5, I suggest using a time.sleep to pause the FT as it runs, so that we can see what the Selenium browser is showing on screen. We can’t do that on PythonAnywhere, because the browser runs in a virtual display. Instead, you can inspect the live site, or you could “take my word for it” regarding what you should see.

The best way of doing visual inspections of tests that run in a virtual display is to use screenshots. Take a look at Chapter 20 if you’re curious—there’s some example code in there.

The Deployment Chapter

When you hit Chapter 8, you’ll have the choice of continuing to use PythonAnywhere, or of learning how to build a “real” server. I recommend the latter, because you’ll get the most out of it.

If you really want to stick with PythonAnywhere, one option would be deploy a second copy of your app on a different domain. You’ll need your own domain name, and a paid account on PythonAnywhere. But even if you don’t do that, you should still make sure you can run the FTs in “staging” mode against the real site, rather than using the threaded server from LiveServerTestCase.


If you are using PythonAnywhere to follow through with the book, I’d love to hear how you get on! Do send me an email at .

[37] You could run the Django dev server from a console instead, but the problem is that PythonAnywhere consoles don’t always run on the same server, so there’s no guarantee that the console you’re running your tests in is the same as the one you’re running the server in. Plus, when it’s running in the console, there’s no easy way of visually inspecting how the site looks.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required