Janet Riley

Lightning Talk: Instant Testing with PyTest

November 23, 2014 | In python / talks

Notes from my PyLadies Boston lightning talk.

Instant Testing with PyTest

Motivation

Every day when I leave the house I check certain things:

  • do I have my keys?
  • do I have my wallet?
  • do I have my phone?
  • are the dogs inside?
  • is the stove off?

It's not a long list, but I run through it every time I go out. Wouldn't it be great if there were a sensor to check for me and would flash a green or red light by the door? Instant feedback, no chance of forgetting.

We do similar checks every time we change our code. Does my site still work? Does this feature still work? The more features we add, the bigger the checklist grows. Automated testing tools can verify functionality for us.

What's the shortest path to get started? Introductory tutorials get complicated quickly. You just want to write a few tests, and they're talking about your entire testing strategy.

You can accomplish a lot with a few commands. If I wrote a Python testing cheatsheet on my hand for an exam, this is what I would include.

Use PyTest

Of the many good Python test libraries, I pick PyTest. PyTest sells itself as 'no boilerplate!' and 'compatible everywhere!' That simplicity makes it a good place to start. Reevaluate when your testing gets more complex. For now, there's plenty of room to grow.

Install PyTest with pip.

pip install pytest

Write a test

Let's see what a test looks like.
True Test Driven Development believers begin with a test that fails.

Here's where our code under test will go:

And here's our first test.

Run tests

Run tests from the command line with the py.test command:
py.test test_checklist.py

PyTest runs all the function whose names begins with 'test_' .

pytest failing base case

A failing test! Now we're cooking.

Let's build out our code so the test passes.

PyTest passing case

Write tests with assert

assert is the magic word to test something. Use the keyword "assert" followed by any true or false statement. If the statement is true, it passes. If false, it fails.

Expand tests as you go. Let's make the Checklist assess whether I'm ready to go:

... and refactor the tests to reflect our changes.

Test error handling with exceptions

Normally an exception stops a program in its tracks. How can we test our error handling without stoping the test? Surround the function call with a pytest.raises block.

Mighty oaks from little acorns grow

assert and pytest.raises will take you a long way in testing.

When your test suite grows, PyTest has more features to manage complexity. These include simplifying setup with fixtures, doing multiple runs with parameterized input, and skipping test cases temporarily with xfail.

The cheatsheet

These are the essentials to get started:
* pip install pytest
* py.test your_test_file.py
* assert things with assert
* check errors with pytest.raises(ExpectedException)

( As promised, it fits on one hand.)

Where to from here?

  • See PyTest's get started page.
  • Write some tests. Start testing a function that is critically important to get right, or by adding tests for everything going forward from today.
  • Once asserts are familiar, learn more about strategy. Ned Batchelder's PyCon talk is a good introduction to unit testing.