Practical Tips on Testing¶
This chapter contains a collection of tips on test strategies and tools, such as test automation libraries, that help you make BDD a successful experience.
Seriously, Don’t Test the User Interface¶
Warning
While you can use behave to drive the “user interface” (UI) or front-end, interacting with the model layer or the business logic, e.g. by using a REST API, is often the better choice.
And keep in mind, BDD advises your to test WHAT your application should do and not HOW it is done.
If you want to test/exercise also the “user interface”, it may be a good idea to reuse the feature files, that test the model layer, by just replacing the test automation layer (meaning mostly the step implementations). This approach ensures that your feature files are technology-agnostic, meaning they are independent how you interact with “system under test” (SUT) or “application under test” (AUT).
For example, if you want to use the feature files in the same directory for
testing the model layer and the UI layer, this can be done by using the
--stage
option, like with:
$ behave --stage=model features/
$ behave --stage=ui features/ # NOTE: Normally used on a subset of features.
See the More Information about Behave chapter for additional hints.
Automation Libraries¶
With behave you can test anything on your application stack: front-end
behavior, RESTful APIs, you can even drive your unit tests using Gherkin
language. Any library that helps you with that you usually integrate by
adding start-up code in before_all()
and tear-down code in after_all()
.
The following examples show you how to interact with your Python application by using the web interface (see Seriously, Don’t Test the User Interface above to learn about entry points for test automation that may be better suited for your use case).
Selenium (Example)¶
To start a web browser for interaction with the front-end using
selenium your environment.py
may look like this:
# -- FILE: features/environment.py
# CONTAINS: Browser fixture setup and teardown
from behave import fixture, use_fixture
from selenium.webdriver import Firefox
@fixture
def browser_firefox(context):
# -- BEHAVE-FIXTURE: Similar to @contextlib.contextmanager
context.browser = Firefox()
yield context.browser
# -- CLEANUP-FIXTURE PART:
context.browser.quit()
def before_all(context):
use_fixture(browser_firefox, context)
# -- NOTE: CLEANUP-FIXTURE is called after after_all() hook.
In your step implementations you can use the context.browser
object to
access Selenium features. See the Selenium docs (remote.webdriver
) for
details. Example using behave-django:
# -- FILE: features/steps/browser_steps.py
from behave import given, when, then
@when(u'I visit "{url}"')
def step_impl(context, url):
context.browser.get(context.get_url(url))
Splinter (Example)¶
To start a web browser for interaction with the front-end using
splinter your environment.py
may look like this:
# -- FILE: features/environment.py
# CONTAINS: Browser fixture setup and teardown
from behave import fixture, use_fixture
from splinter.browser import Browser
@fixture
def splinter_browser(context):
context.browser = Browser()
yield context.browser
context.browser.quit()
def before_all(context):
use_fixture(splinter_browser, context)
In your step implementations you can use the context.browser
object to
access Splinter features. See the Splinter docs for details. Example
using behave-django:
# -- FILE: features/steps/browser_steps.py
from behave import given, when, then
@when(u'I visit "{url}"')
def step_impl(context, url):
context.browser.visit(context.get_url(url))
Visual Testing¶
Visually checking your front-end on regression is integrated into behave in a straight-forward manner, too. Basically, what you do is drive your application using the front-end automation library of your choice (such as Selenium, Splinter, etc.) to the test location, take a screenshot and compare it with an earlier, approved screenshot (your “baseline”).
A list of visual testing tools and services is available from Dave Haeffner’s How to Do Visual Testing blog post.