Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
Python web testing for the Ruby programmer

Ruby has a couple of well-known libraries for unit testing, mocking and stubbing HTTP interactions. My typical toolset includes RSpec, WebMock and VCR. I had the chance to work on a Python project recently and did some investigation into similar libraries for Python.

General testing libraries

The two most popular python test libraries + runners are py.test and nose. A neat feature of py.test is that is gets by with only the builtin ‘assert’ keyword: the test runner expands assertion failures to show exactly how the assertion failed e.g.:

===================== FAILURES =====================
_____________________ test_web _____________________

    def test_web():
      resp = c.get('/')
>     assert resp.status == '404'
E     assert '200 OK' == '404'
E       - 200 OK
E       + 404

lib/test_snack_overflow.py:9: AssertionError
============= 1 failed in 0.24 seconds =============

One gotcha is that py.test silences stdout by default, so you’ll need to pass the -s flag to see any debugging output.

Test doubles

The mock library can be installed through pip for Python 2 and comes as part of the standard library of Python 3. As an example of mocking out an environment variable using a context manager:

with mock.patch.dict('os.environ', {'APP_NAME': 'HelloWorld'}):
assert app.name = 'HelloWorld'

There’s also a decorator form, nice because it clearly states what modules are being mocked in your tests:

@mock.patch('crazyservice')
def test_nationals_stats(_crazyservice):
_crazyservice.date = "2013-04-06 12:31 AM"

Another gotcha for newcomers to Python testing: not all methods can be replaced at runtime. A good example is stubbing DateTime.now in ruby: the equivalent monkeypatching in python raises:

TypeError: can’t set attributes of built-in/extension type ‘datetime.datetime’

as these methods cannot be replaced in CPython. You’ll need to write a wrapper function and mock that out instead in your tests.

Web testing

The werkzeug WSGI library includes simple utilities to make request testing as easy as with rack-test. Another library I’m a big fan of is HTTPretty, which is similar to Ruby’s WebMock or FakeWeb. Finally, Ruby’s VCR gem is invaluable for recording real HTTP interactions. A port exists on python called vcr.py.

 

Comments
  1. Kevin says:

    Thanks for this intro! It’d be great for more expansion – I guess I am just too attached to Rspec and Jasmine to truly be enjoying python’s testing so far, but I hope it gets better

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *