1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
.. _id.practicaltips:
=========================
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 :pypi:`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:
.. code-block:: bash
$ behave --stage=model features/
$ behave --stage=ui features/ # NOTE: Normally used on a subset of features.
See the :ref:`id.appendix.more_info` 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
:pypi:`selenium` your ``environment.py`` may look like this:
.. code-block:: python
# -- 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 :pypi:`behave-django`:
.. code-block:: python
# -- 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))
.. _Selenium docs: https://seleniumhq.github.io/selenium/docs/api/py/api.html
Splinter (Example)
------------------
To start a web browser for interaction with the front-end using
:pypi:`splinter` your ``environment.py`` may look like this:
.. code-block:: python
# -- 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*:
.. code-block:: python
# -- 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))
.. _Splinter docs: http://splinter.readthedocs.io/en/latest/
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.
.. _How to Do Visual Testing:
http://testautomation.applitools.com/post/105435804567/how-to-do-visual-testing-with-selenium
|