Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

codeA guest post by Wayne Witzel III who resides in Florida and is currently working for Slashdot Media as a Senior Software Engineer building backend systems using Python, Pylons, mongodb, and solr. He can be reached at @wwitzel3.

The Pyramid web framework provides a great testing module (pyramid.testing) that gives you a lot of convenient methods for setting up and tearing down your application. The module also provides you with easy access to mock request and resource objects that you can use in your unit and functional tests.

behave is a behavior-driven development library for Python. Behavior-driven development (or BDD) is a software development technique that encourages collaboration between developers, QA, and non-technical or business participants in a software project. It does this by using a natural language called Gherkin. This language allows you to create human readable tests that you can also use and run as feature tests against your application.

This post will show you how to get started using Pyramid and behave together. I recommend you download and setup the basic project skeleton (pyramid_behave) that I have created for this post. I will show you how to do this in the “Our First Feature” section.

See: pyramid_behave repository.

Quick behave Primer

behave tests are written in .feature files. You create a high-level feature, like arithmetic.feature, and inside that feature file you implement scenarios using the Gherkin language I mentioned before. Here is a trivial example:

After you have done that, you implement the actual Python steps to execute the scenario and make any assertions:

You use the behave decorators (given, when, then) to connect your scenario text to the step methods. Each method must accept a context. The Context object is generated by behave and allows you to store any arbitrary data you need for your steps. We will be working with the context in the examples that follow.

Now that you have a features file and a set of steps, you assemble them in a directory as basic.feature and steps/basic.py and run the behave command:

Our First Feature

To get started you should checkout the pyramid_behave git repository and get everything installed.

This will install all of the required packages for you and allow you to easily follow along. For our first feature you will want to be on step1 in the repository:

We will create behave.ini at the root of the project. We do this to control how the test runner will format the output and point behave to our features directory. In our case it looks like this:

Now we will create our first feature. We will do this by creating the pyramid_behave/tests/features/todo.feature. This will define the feature for adding new items to our todo list.

We can save that file and run the behave command. We will see the output for the failing feature and a message. The message informs us that we are missing steps and will generate some helpful code for us to make it easy to begin the process of implementing each step for this feature’s scenario. We will do that by creating pyramid_behave/tests/features/steps/todo.py.

First, we will implement the given step. This step is really here to allow us to setup the context we need for the next step. In our case we need to setup some database access and provide access to that for each step. Use the given step as a place for putting the system in to a known state, so things like database setup or earlier actions like logging in can go here:

Now we move on to our when step. This step will take our context.text data “new todo task” and actually create our new task. We will then assign it to the context so the then step can perform its assertions. Consider the when step as a place where the key action takes place, or things like interacting with a view or web page (we do that later).

Finally we are in our then step. This step takes the todo entry we assigned to the context, pulls a listing or all of the todos, and asserts that the context todo is in the listing. The then step is for observing outcomes and verifying that the data we expect is present and correct.

You can now checkout step1.complete and run behave to see the successful results and review the code including imports:

A Better Way

Now that you’ve created your first feature, right away you can see there will be some problems. Mainly the setUp and tearDown methods you normally have are not present and there is no clear way for how we actually test views. Fortunately there is a better way to setup behave for testing with Pyramid and that is by using a custom environment.py file. This file is a behave convention that allows us to have setUp and tearDown steps like registering a testing database and bootstrapping our application.

Since behave supports many different steps, there are a few more options we have access to in our environment.py over what you traditionally see with other testing libraries.

Lets get started by checking out step2 in the pyramid_behave repository.

You will now have a test.ini in the root directory. We are using this to define a database that is safe to tear down and rebuild after each scenario. We can now begin the process of defining our environment for behave.

First, we will setup the before_all. Code contained within this method will run only once for the entire set of features:

This creates our settings, using our test.ini, which uses an in-memory database, and sets up the sqlalchemy engine. Now we can setup the before_scenario method. This, as you might assume, is called before each scenario is run. Think of this as your traditional setUp method. We will create our database here:

Finally, we can create our after_scenario. You can think of this like you would tearDown. We will clean up our database session and run the Pyramid testing tearDown here:

Now that we have our newly setup environment.py, we can go ahead and refactor the existing tests to take advantage of it and after that, we will write a feature that tests our Pyramid view.

Refactoring

We can make our old test take advantage of the new environment.py file by simply deleting some lines of code from the current test. We will also make our Given a little more flexible by dynamically passing in the todo text. These changes look like this:

As you can see, we have a nice clean set of tests around creating a new todo task in the database and we’ve removed all of the boiler plate setup out in to the environment.py.

View Testing

Now that we have our environment setup for Pyramid testing, we can actually test our view. Let’s create a very simple view in views.py called todo that just fetches out a given todo from the database using the id.

We will also add a simple route to __init__.py:

Now in our todo.feature we can create a scenario that will represent using this view.

Next we take advantage of behave, allowing us to parameterize our match text, so we can easily fetch the ID from the feature, instead of hard coding it in to the test. Then we use the same familiar testing tools from Pyramid to implement our new when step.

Then finally we implement our new then step which in this case, just ensures that the view returned a dictionary with a todo item in it.

You can now checkout step2.complete and run behave to see the tests pass.

Wrapping Up

You should now be comfortable enough to get started with using behave for your own Pyramid projects. I encourage you to reference the pyramid_behave repository as well as the Behave and Pyramid testing documentation.

For more details about Python, see the Safari Books Online resources referenced below.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Learning Python, 5th Edition will help you quickly write efficient, high-quality code with Python. It’s an ideal way to begin, whether you’re new to programming or a professional developer versed in other languages.
Hello! Python fully covers the building blocks of Python programming and gives you a gentle introduction to more advanced topics such as object-oriented programming, functional programming, network programming, and program design. New (or nearly new) programmers will learn most of what they need to know to start using Python immediately.
Violent Python shows you how to move from a theoretical understanding of offensive computing concepts to a practical implementation. This book demonstrates how to write Python scripts to automate large-scale network attacks, extract metadata, and investigate forensic artifacts. It also shows how to write code to intercept and analyze network traffic using Python, craft and spoof wireless frames to attack wireless and Bluetooth devices, and how to data-mine popular social media websites and evade modern anti-virus.

Tags: BDD, behave, Behavior-Driven Development, Pyramid, Python, testing,

Comments are closed.