Now that you're done prepping up your programming environment let's dive in on the directory structure and the components needed in order to run your first API tests. At the end of this article you should have your project scaffolding ready and you should have a good understanding on feature files and steps implementations.

Behave Directory Structure

Here's a sample of a Behave Project structure that we will be adopting as we create a sample project that automates the integration tests of a REST API. And as you can see the project structure is very simple and easy to follow.

Project Folder
├── features
│   ├── steps
│   │   ├── step_get_pokemon.feature
│   │   ├── step_get_item.feature
│   ├── feature_to_be_tested.feature
│   ├── feature_to_be_tested.feature

To summarize you just need a Project root Folder and inside the project root folder you'll have the following

  1. features directory
  2. feature files - Basically those files that ends with .feature extension. Feature files are similar to test cases
  3. a steps sub-directory which resides inside the features directory
  4. step implementation files which you can find inside the steps directory. This is where you'll write the python code which will drive the API requests. Step implementation files ends with .py extension
This setup is the bare minimum project structure that you need in order to run tests in Behave for demonstration purposes. We will probably update and make some adjustments in the future by adding  environment.py for environment controls or a configuration file (.ini). But for now let's settle with this kind of setup.

Now that you have an idea on the directory structure, go ahead and manually create your project directories.  On the next section I'm going to give a pass through on creating feature files and how to code the scenarios you've written in steps implementation

A Quick Look at Feature Files

An example of a Feature file

What you see above is an example of a basic feature file. You can easily create one by creating a text document and saving it with a .feature extension. I highly suggest you download Visual Studio Code if you don't have a Text Editor  yet. It recognizes feature files and let's you integrate a plugin where it adds syntax highlighting to get you familiar with the basic Gherkin Keywords.

Breaking Down Gherkin Keywords and Structure

  • Feature - this keyword should be followed with a colon : and then a descriptive phrase of what the feature is about. A nice guide in writing descriptive Features is to follow a user-story format wherein you should specify the intended user, in this case it is the  Logged In User followed by it's Business Value which is to increase revenue and customer engagement.
  • Scenario - is equivalent to Test Scenarios and is written similar to a  Feature which is followed by a colon and a description of what you want to test. After writing a nice test description you should indent it and add Given, When and Then which are similar to Test Steps

Test Steps

The following keywords are found under a Scenario. You do not need to write a colon : after the keywords the way Features and Scenarios are written. But they should be indented and separated by newline

  • Given - this is the initial state or the test preconditions.
  • When - is the intended action.
  • Then - is the desired outcome of the scenario

The above structure is the bare minimum format that you need in order to have a readable Behavior Driven Test if you are going to use Python's Behave in driving your tests.

Aside from Given , When and Then there are two additional keywords that I did not mention which is And and But they are used to augment test steps in order to have more readable Test Steps. I will discuss an in depth article about writing Feature Files in the near future but for now let's start on the very basic first.

Translating Test Steps in Feature Files to Python Code

Now that you have a Feature File with proper format we need to map the Test Steps that you've defined in the Scenario to Python Code. Python code are stored under the steps sub directory inside features and can be spotted by the .py extension. To those who are new to Behave I usually tell them that you need to map one feature file to one Python file but it's not usually the case. But for easier mental mapping a 1 is to 1 guide is easier to remember for test organization.

Converting the example Feature File that I listed above you'll end up a python file that looks like this.

from behave import given, when, then

@given('a logged in user which has an active session in "{website}"')
def step_impl(context, website):
    # some python code to setup state
    pass
    
@when('the user visits "{website}"')
def step_impl(context, website ):
    # some python code to emulate action
    pass
    
@then('the user is prompted with a pop up notification of the voucher that they can use')
def step_impl(context):
    # some python code to check desired outcome
    pass 

Breakdown of Python Code

the first line from behave import given, when, then means that you need to use the annotations given, when and then that resides inside the behave package. Annotations are not that common in python but behave makes use of it to properly map the Test Steps inside the feature file. To use them you can check out the code below

@given('a logged in user which has an active session in "{site}"')

and then you need to follow it up with a function definition

def step_impl(context, website):
    # some python code to setup state
    pass

If you'll notice, we replaced http://www.sample-shop.com with {website} and that is because you can use it to parameterize the test steps. Parameterizing your steps implementation will save you a lot of time as you don't need to individually update your python code. All you need to do is update your feature files and your code will adapt on what you supplied between the double quotes ".

Next Steps...

Now that you have a feel on Behave's Project Structure we will be integrating Python's Requests Module. I'll be writing a brief review on HTTP Messages and demonstrate how to test REST APIs on my next blog post.