Python Behave Tutorial: A Comprehensive Guide to Behavior-Driven Development (BDD)


In this tutorial, we'll explain each and every aspect of Behavior Driven Development. This BDD Python tutorial will help you create and design your automation tests and framework.

Table of Content

1. What is BDD?

2. What is Gherkin Language in BDD?

3. What is Behave in Python?

4. Installing and Setup Behave

5. Project Structure for Behave Python (BDD)

6. Feature Files, Step Functions and Other Files in Behave

  • Feature File
  • Step Functions
  • Step Parameters
    • Passing String Param from Feature File
    • Passing Integer Param from Feature File
  • environment.py file
  • behave.ini file

7. Run Feature files in Behave

  • Run a single feature file
  • Run multiple feature files
  • Generate JUNIT xml reports with behave
  • Run feature files with Python suite file


Upcoming Tutorials:

8. API Automation Testing with BDD Python (Behave)

9. Selenium Automation with BDD Python (Behave)




1. What is BDD?

BDD stands for Behavior Driven Development. BDD is an agile process of development. It encourages non-technical or business teams to collaborate with developers and QA during the development phase of the software. It was originally developed in 2003 by Dan North. This development process is believed to be inspired by the TDD which is Test Driven Development. You can also say that BDD is an extension of TDD.

So, the key idea in BDD is to,
  • Write the test before the development code is written, which should actually fail.
  • Then make that failing test pass after the development code is written.
In BDD, test cases are written in natural language which non-programmers generally business people can understand. Tests are derived from features directly in BDD which certainly give an edge to BDD over other Testing techniques where tests are derived from Technical Specifications. So, it improves the communication and understanding between Developers and Businesses regarding the required software behavior which is the core goal of BDD.

We are going to explain BDD Automation Testing with Python's Behave module.

2. What is Gherkin Language in BDD?

Tests are written using the Gherkin language in BDD. Gherkin language is basically the normal English language with some basic rules. It has introduced a few keywords with which the tests should be written. And these Gherkin language tests are mapped with code written by automation testers which actually gets executed when Gherkin tests are being executed. Gherkin language is used by Behave and many other BDD tools like., lettuce, cucumber, etc. Behave in Python uses the following eight keywords of the Gherkin language:
  1. Given
  2. When
  3. Then
  4. And
  5. Feature
  6. Background
  7. Scenario
  8. Scenario Outline
Here is an example of a BDD test written using Gherkin language for the Add Product to Cart functionality.
Feature: Add product to cart

    Scenario: Login and click summer dresses
      When I open amazon website
      And I login with username '[email protected]' and password 'Test@123'
      Then I hover on women menu item and click summer dresses
To understand this example better let's understand the following aspects:
  • Feature gives a high-level description of the software feature.
  • Given is pre-condition.
  • When is some action.
  • Then is the expected outcome.
  • And is used to have additional steps along with Given, When, or Then statements. 


3. What is Behave in Python?

Behave is a Python module for implementing the BDD approach in Development or Testing code. Behave lets you use Gherkin language to write tests. It lets you create 
  • Feature Files like., Login.feature, Product.feature
  • Step Definition File like., steps.py
  • behave.ini or setup.cfg
  • environment.py
These files are the core of BDD. Some pointers about these files.
  • We can create as many feature files as we want or need, say one feature file for one feature under test. 
  • But one step definition and one behave.ini file. 
  • The step definition file is the file where all the code is written and mapped to the steps/lines written in the feature file. 
  • And behave.ini is basically a configuration file for the BDD project. 
  • And the environment file is for integrating some hooks to our step implementations like before_all, before_feature, after_feature, etc.
  • We'll learn more about these files as we progress through this tutorial.

4. Install Behave

Behave can be installed using the pip command or using the GitHub repo with the setup.py file. You just have to open a command prompt and execute the following commands.

4.1. Using the pip command

PYPI distribution URL for Behave - https://pypi.org/project/behave/
  • For Windows - pip install behave
  • For Linux - the pip3 install behave

4.2. Using GitHub Repo

4.3. Download and Install PyCharm IDE

You can download and install PyCharm IDE from - https://www.jetbrains.com/pycharm/download/#section=windows

PyCharm has two variants, Professional and Community. The professional variant is licensed and the Community variant is freeware. You can use the Community variant.

5. Project Structure for Behave (BDD)

Let's understand the structure of a Behave project,
  • Create a new Python project in PyCharm. 
  • And then create a features directory inside it. All the .feature files will be created under this directory.
  • Create a steps directory inside the features directory. The step definition file which is steps.py will be created in this steps directory.
So, a simple Behave project will look like this:

+--features/
|   +--steps/       # -- Steps directory
|   |    +-- *.py   # -- Step implementation or use step-library python files.
|   +-- *.feature   # -- Feature files.


Although a more complex project looks like

+-- features/
|     +-- steps/
|     |    +-- website_steps.py
|     |    +-- utils.py
|     |
|     +-- environment.py      # -- Environment file with behave hooks, etc.
|     +-- signup.feature
|     +-- login.feature
|     +-- account_details.feature

Project Structure in PyCharm:


6. Feature Files and Step Functions in Behave

Now we'll learn how to write feature files and implement steps written in feature files using Gherkin language will be mapped to Python code. It's also called Step Implementation in technical terms.

6.1. How to Write a Feature File

As already described in this post a feature file is a collection of steps written in the native language, generally English (but Behave supports other languages as well). These steps are written using some pre-defined keywords of the Gherkin language, like Given, When, Then, AND etc. In the feature file, Feature is the largest entity, then comes the Scenario. A feature can have multiple scenarios in it. A Scenario is basically a test case when it comes to automation testing. Let's understand the different keywords and symbols that can be used in a feature file:
  • Feature: List of scenarios.
    • Background: List of steps run before each of the scenarios
    • Scenario: Business rule through the list of steps with arguments.
      • Given: Some precondition step
      • When: Some key actions
      • Then: To observe outcomes or validation
      • And, But: To enumerate more Given, When, Then steps
    • Scenario Outline: List of steps for data-driven as an Examples and <placeholder>
      • Given: Some precondition step with <name>
      • When: Some key actions with <value>
      • Then: To observe outcomes or validation as <status>
      • Examples: Container for s table
        • | name  | value | status  |
          | name1 | 5 | success |
          | name2 | 7 | Fail |
  • | (Data Tables)
  • """ (Doc Strings)
  • @ (Tags/Labels): To group Scenarios
  • < > (placeholder)
  • ## (Comments)
  • "" String

Sample Feature Definition Template:

#Author: vb
Feature: Title of your feature
  I want to use this template for my feature file

  Scenario: Title of your scenario
    Given I want to write a step with precondition
    And some other precondition
    When I complete action
    And some other action
    And yet another action
    Then I validate the outcomes
    And check more outcomes

  Scenario Outline: Title of your scenario outline
    Given I want to write a step with <name>
    When I check for the <value> in step
    Then I verify the <status> in step

    Examples: 
      | name  | value | status  |
      | name1 |     5 | success |
      | name2 |     7 | Fail    |

Now let's create a feature file named Login.feature in your "features" directory.

Login.feature

Project Path: MyProject/features/Login.feature

#Author: vb
Feature: Login to portal

  # Setup steps for all scenarios of this feature
  Background: Given inputs for this feature
    Given xyz website and it's DB is up

   # Test Case 1
  Scenario: Test Login Functionality
    When I open xyz website
    And I login with username '[email protected]' and password 'abc@123'
    Then I verify that I successfully logged in
    And  I log out

Alright, we have created a feature file, now it's time to implement its step functions in the Python module. 

6.2. Step Functions

Step functions are the implementation of the feature file steps. They are implemented in Python modules present in your "steps" directory. All the Python files (.py) are loaded before executing your features because .py files are used to search the step implementations.

Let's create a Python module inside your project's "steps" directory and name it TestSteps.py.

TestSteps.py

Project Path: MyProject/features/steps/TestSteps.py

from behave import *


@given("xyz website and it's DB is up")
def step_impl(context):
    raise NotImplementedError(u'STEP: Given xyz website and it\'s DB is up')


@when("I open xyz website")
def step_impl(context):
    raise NotImplementedError(u'STEP: When I open xyz website')


@then("I verify that I successfully logged in")
def step_impl(context):
    raise NotImplementedError(u'STEP: Then I verify that I successfully logged in')


@step("I log out")
def step_impl(context):
    raise NotImplementedError(u'STEP: And  I log out')



Step File Explanation:
  • Importing Behave: You must have noticed that the first line in the steps file is to import behave module. 
  • Annotations: You can also observe that every step implementation function has an annotation like., @given, @when, @then, and @step. These annotations are mapping these functions to the corresponding steps in feature files.
  • The context in Behave: Context is a very important feature in the step implementation file. If you want to share your function variables with other functions then you have to declare them with context. Like.,
    • context.iam_token = Token.get_iam_token()
    • If you have declared this iam_token variable in first step_impl function
    • then it would also be available to all the other step_impl functions.

6.3. Step Parameters

You can also use parameters in your steps in feature files. This is really a nice feature to have because by using this feature you reduce the number of steps by parameterizing your step. 

For example., if you have written a step for clicking on a link as "I click on Home". And if you have multiple links then you have to create as many steps as links. But if you parameterize this step like "I click on 'link' ", 'link' is a variable here. So, now we'll pass the variable value from steps, and in the steps file we write our logic to click on the link which is requested by the feature file.

6.3.1 Passing String Parameter from Feature File

Let's learn how we can pass a string value parameter from the feature file to the steps file (.py) from the below example.

Links.feature


Scenario: Test menu links
  When I click on 'Home' link
  And I click on 'Dress' link


We have created only one step and parameterized it with link value by writing it in quotes. Now, let's create the step implementation function for this step.

Steps.py


@given("I click on '{link_text}' link")
def step_impl(context, link_text):
    # Call Click link function
    click_link(link_text)


So, you can see the syntax to get the string parameter from the feature file is to get the value in '{string_value}'. And this variable then can used further in the step_impl() function.

6.3.2. Passing Integer Parameter from Feature file

Let's take a look at the example feature and step files to understand how to pass integer values from the feature file to the steps Python file.

SignUp.feature


Scenario: Test Sign-UP form
  Given Age of the employee is '26'


Steps.py


@given("Age of the employee is '{age:d}'")
def step_impl(context, age):
    # Enter age 
    enter_value(age)


6.4. Environment File in Behave

The environment.py module can have functions that can run before and after your tests. Let's take a look at those functions and their behavior.

i. before_all(context) and after_all(context) - These run before and after the whole execution.

ii. before_feature(context, feature) and after_feature(context, feature) - These run before and after each feature is executed.

iii. before_scenario(context, scenario), after_scenario(context, scenario) - These run before and after each scenario is run.

iv. before_step(context, step), after_step(context, step) - These run before and after every step. 

Sample environment.py

import logging


def before_all(context):
     print("Executing before all")

def before_feature(context, feature):
     print("Before feature\n")
     # Create logger
     context.logger = logging.getLogger('automation_tests')
     context.logger.setLevel(logging.DEBUG)

def before_scenario(context, scenario):
    print("User data:", context.config.userdata)

def after_scenario(context, scenario):
    print("scenario status" + scenario.status)
    context.browser.quit()

def after_feature(context, feature):
            print("\nAfter Feature")

def after_all(context):
	print("Executing after all")


6.5. behave.ini

It's a configuration file for behave project, a sample behave.ini looks like this,

Sample behave.ini:

[behave]
stderr_capture=False
stdout_capture=False
log_capture=False
show_timings=True
verbose=True
color =True


7. Run Your (Test) Feature files in Behave Project

Behave have many command line arguments, which can be used to run our project code. You can have a list of all available options with behave help command.

behave --help

i. Run a Single Feature file: 

You can run a single feature file with the following command,

behave features\Login.feature

ii. Run Multiple Feature files: 

And run all the feature files by giving the features directory path to behave command,

behave features\

iii. Generate JUNIT xml Test Report: 

You can also generate the JUnit test report in XML format by using --junit parameter with behave.

behave features\ --junit


iv. Run Feature files with a Python Suite file: 
You can also create a suite.py file in your project and execute your feature files by using that Python file with different Behave command line parameters.

Sample Suite.py file

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
from behave import __main__ as runner_with_options


if __name__ == '__main__':
    sys.stdout.flush()

    # Join Feature Files
    featureFileFolder = '../tests/'

    # Runner Option set to junit
    commonRunnerOptions = ' --no-capture --junit --junit-directory ../test-results/e2e '

    # Complete Suite
    fullRunnerOptions = commonRunnerOptions + featureFileFolder
    var = runner_with_options.main(fullRunnerOptions)


8. API Automation Testing with Behave in Python (BDD)

Coming Soon...

9. Selenium Automation with Behave in Python (BDD)

Coming Soon...

Author
Passionately working as an Automation Developer for more than a decade.

Follow Techlistic

YouTube Channel | Facebook Page | Telegram Channel | Quora Space
If you like our blogs and tutorials, then sponsor us via PayPal

Comments

  1. I came across your blog post on Austin metal roofing, and I must say it's an excellent resource for homeowners like myself. Metal roofing is gaining popularity in Austin due to its numerous benefits, and your article effectively highlights why it's a great choice. The extreme weather conditions we experience in Austin, including scorching summers and occasional storms, make the durability and resilience of metal roofing highly desirable. Your insights on how metal roofs can withstand these challenges and provide long-lasting protection were truly informative.
    Regards,
    Alpha Team Roofing

    ReplyDelete
  2. Share Personal Experience: Relate a relevant personal experience related to the blog post's topic to enhance the discussion.Digital marketing IT Center

    ReplyDelete
  3. "Exceptional tutorial! This comprehensive guide to Python Behave and Behavior-Driven Development is a game-changer. Clear explanations, practical examples, and step-by-step approach make it an indispensable resource for developers. Outstanding work!"

    ReplyDelete
  4. "Incredible resource! This Python Behave tutorial is a gem for developers diving into Behavior-Driven Development. Comprehensive coverage, real-world examples, and a user-friendly approach make it an essential guide for mastering BDD. Highly recommended!"

    ReplyDelete

Post a Comment

Popular posts from this blog

17 Best Demo Websites for Automation Testing Practice

Automation Practice: Automate Amazon like E-Commerce Website with Selenium

Top 7 Web Development Trends in the Market

Top Mobile Test Automation Tools for Efficient App Testing: Features and Cons

Selenium IDE Tutorial: How to Automate Web Testing with Easy-to-Use Interface

Install Appium and Dependencies for Mobile Automation

How to Take Screenshots with Selenium WebDriver

Mastering the Java Interview Questions: OOPS Concepts and Code Examples

Find Broken Links on Webpage with Selenium Automation