Django Testing : Taking a Quick Dip into Behavior Driven Developmentby Applied Informatics
Off late we have been learning how to make our code Behave-friendly. Behave is a python toolkit for supporting Behavior Driven Development within your applications. BDD provides a more collaborative, intuitive and developer friendly methodology which tests the application by the behavior the user expects it to have.
The term has recently been associated with the Gherkin Syntax. The Gherkin syntax is a human-readable DSL used for writing functional tests. If you develop in Python you can use either Behave or Lettuce. We will focus more on Behave now, since it has more compatibility than Lettuce. So to get started with learning how to (use) Behave:
1. First install a plugin called django-behave.
If using pip,
$ pip install django-behave
Then make a module for the BDD tests:
$ mkdir bdd_tests
2. Add a steps and features directory as well:
*If the feature file is called “behave_test.feature” then the steps file must be named “behave_test.py”
The human-readable element is called the “feature,” which is written in Gherkin. Each of the Gherkin is mapped to a function that contains selenium code. These are necessary to implement the “Step.”
Here is a sample feature file:
“”” Feature: Lists I want to see all the lists I have created in one page Scenario: Create a list and see them on the main page When I create a list with an item “bananas” And another item “oranges” Then I will see a button to open up “list1” When I click the button to “list1” Then I will see a list that includes “bananas” and “oranges” “””
Given/When/Then matches the pattern from regular unit tests of a setup leading to an exercise which then leads to an assert.
3. Now on to the “step” functions to implement our feature files into code.
$ behave bdd_tests
In the terminal, it will tell us the steps to implement.
“”” $ behave bdd_tests Feature: Lists Scenario: #lists.feature:1 When I create a list with an item “bananas” #None And add another item “oranges” #None Then I will see a button to open up “list1” #None When I click the button to “list1” #None Then I will see a list that includes “bananas” and “oranges” #None Failing scenarios bdd_tests/features/lists.features:1 0 features passed, 1 failed. 0 skipped 0 scenarios passed, 1 failed, 0 skipped 0 steps passed, 0 failed, 0 skipped, 10 undefined Took 0m0.000s You can implement step definitions for undefined steps with these snippets: @when(when I create a list with an item “bananas”) def step_impl(context): assert False @when(add another item “oranges”) def step_impl(context): assert False @then(I will see a button to open up “list1”) def step_impl(context): assert False @when(I click the button to “list1”) def step_impl(context): assert False @then(I will see a list that includes “bananas” and “oranges”) def step_impl(context): assert False “”” Copy and past the snippets into the lists.py file in the steps folder.
Your lists.py should look like this:
“”” from behave import * from django.cong import settings @when(when I create a list with an item “bananas”) def step_impl(context): context.browser.get(context.server_url) context.browser.find_element_by_id(‘id_text’).send_keys(first_tem_text) context.brownser.
The context variable is a global variable that is passed to each step to be executed. It can store all the information to be parsed and confirmed between the steps. It is similar to “self” in unit tests. The context variable must be set up in environment.py.
bdd_tests/features/environment.py. from selenium import webdriver def before_all(context): context.browser = webdriver.Firefox() context.brownser.implicitly_wait(2) context.server_url = ‘http://localhost:8000” def after_all(context): context.browser.quit() def before_feature(context, feature): pass
NOW to implement some DJANGO MAGIC and set up the database and live server before each test. Add bdd_tests to INSTALLED_APPS in the settings file.
$ ./manage.py test bdd_tests --testrunner=djjango_behave.runner.DjangoBehaveTestSuiteRunner
Thats it for the basic set up of behave in Django. In our next post we will get into more details and describe some fun quirks in Gherkin.