We might be interested in starting to incorporate a unit test suite to our project, which is coded in Python (and it uses Redis, PostgreSQL and some third-party libraries, if that bears into the solution). The benefits we want to achieve are:

  1. Once the project is up to speed, we want to be able to specify new behavior quickly and efficiently, to help improve communication and team productivity. Read: We want BDD, but have already started coding without it.
  2. Excellent textual support (i.e. the tests can be read almost as natural text), so as to make it easier to write and read tests.
  3. Ability to automatically run tests (at the very least, to be able to include the running in a Bash script or something like that). We use Windows and Linux for development, and Linux servers, so Linux support is our primary requirement.
  4. Integration with github. I don't know if it is possible, but I've seen some projects in github which have a "Passing" or "Failing" status on them and it would be great to have that for our project.

What are good tools / libraries that can help us do this, and, most importantly, what are good ways to incorporate BDD into a Python project?

Thank you very much! Any suggestions are appreciated.

  • 1
    What has your research uncovered so far? Commented Jan 7, 2013 at 16:05
  • 2
    So far, I have found Behave (pypi.python.org/pypi/behave) which looks like a pretty good approach. I have also seen Lettuce (lettuce.it) which I also like. However, more than packages per se, I am interested in strategies or patterns to use. Commented Jan 7, 2013 at 17:47

4 Answers 4


Try out pyspecs. Making tests easy to read and constantly running during development were two of my main goals in creating this project.

Test Code:

from pyspecs import given, when, then, and_, the, this

with given.two_operands:
    a = 2
    b = 3

    with when.supplied_to_the_add_function:
        total = a + b

        with then.the_total_should_be_mathmatically_correct:

        with and_.the_total_should_be_greater_than_either_operand:

    with when.supplied_to_the_subtract_function:
        difference = b - a

        with then.the_difference_should_be_mathmatically_correct:

Console Output:

# run_pyspecs.py

  | • given two operands 
  |   • when supplied to the add function 
  |     • then the total should be mathmatically correct 
  |     • and the total should be greater than either operand 
  |   • when supplied to the subtract function 
  |     • then the difference should be mathmatically correct 

(ok) 6 passed (6 steps, 1 scenarios in 0.0002 seconds)

While there are BDD frameworks like lettuce or behave (which you better choose by their documentation and examples), you mentioned that you've started without that. So my answer will be related more to this situation.

Original BDD has started with fork of JUnit, which, instead of asking you to name your tests with "testSomething" asked you to name them "shouldDoSomething". That's how you were supposed to be kept focused on things.

So I went the same way in my project. I just started to name tests starting with "test_should_..." and try to give them descriptive names. That's how you're still doing BDD, you're still focused on what exactly should that test do, and it's easy to write something that will convert your test names into normal sentences (if you'll need to, of course). I find this approach a silver bullet since (especially in scripted languages) I never want to waste time on useless names (like test name in case of those BDD frameworks on top).

  • 2
    This. From what I'm reading, Lettuce and Behave are higher-level BDD frameworks, like Cucumber, meant to capture scenarios discovered in conversation with business stakeholders. If you're just communicating with other devs, they can read code; don't worry about using a BDD tool. Any unit testing tool will do the job. I sometimes put my class-level Given, When, Then into comments.
    – Lunivore
    Commented Feb 17, 2013 at 10:02
  • 1
    @Lunivore my point is that if you convert test name from "test_should_get_error_on_registering_user_with_empty_email" to text "Should get error on registering user with empty email" -- any person will understand what it means. Problem takes place when you have description that's too long, then your python test names will just look creepy (and Lettuce will look just fine). Commented Feb 18, 2013 at 10:14

I've been working on a BDD framework called Contexts, inspired by C#'s Machine.Specifications.

Contexts encourages you to write descriptive user-centric sentences for your tests (which is what BDD is all about, really) by spreading out test-cases across a whole class. The arrange/act/assert phases of the test are put in individual short methods, and Contexts figures out which method is which based on their names.

A picture speaks a thousand words, so here's an example from the readme:

import requests

class WhenRequestingAResourceThatDoesNotExist:
    def given_that_we_are_asking_for_a_made_up_resource(self):
        self.uri = "http://www.github.com/itdontexistman"
        self.session = requests.Session()

    def because_we_make_a_request(self):
        self.response = self.session.get(self.uri)

    def the_response_should_have_a_status_code_of_404(self):
        assert self.response.status_code == 404

    def the_response_should_have_an_HTML_content_type(self):
        assert self.response.headers['content-type'] == 'text/html'

    def cleanup_the_session(self):

Contexts also has a number of modern features like parametrised tests, 'assertion-rewriting' (inspired by py.test), and a plugin framework.

I've used Contexts to test itself, as well as on a few other projects (even non-Python projects), and found it to yield understandable, behavioural tests at all levels of the testing triangle (unlike unittest which was not designed for acceptance testing, or Lettuce which was not designed for unit testing).

  • 1
    Wonderful job with Contexts. I'm also a fan of mspec for my C# work. I think this should be the correct answer. Disclosure: I'm the author of pyspecs, which is currently the chosen answer for this question. Commented Mar 2, 2014 at 4:20

I think you should try Morelia: https://morelia.readthedocs.org/en/latest/

It passes your 4-point requirements list:

  1. It's BDD tool built on Python's unittests module
  2. Executed tests are textual description.
  3. If you can automatically run traditional Unit Tests then Morelia can be run same way.
  4. I think the most common CI for github is Travis-CI which can run unit tests so that it can run Morelia.

Not the answer you're looking for? Browse other questions tagged or ask your own question.