Writing good BDD steps¶
The tools provided in Aloe-Webdriver form a reasonably thin wrapper around Selenium and thus make it very easy to write imperative tests. While the occasional imperative test is useful, it is frequently more useful to abstract these into sub-steps of a more declarative test.
For example, take this example from the BBC essay: Tips for writing better feature files.
Here is a bad, imperative example:
Given I am on the login page
When I fill in "username" with "ABC"
And I fill in "password" with "XYZ"
And I checked the "Remember Me" checkbox
And I click on the "Submit" button
Then I should log into the system
And I should see "Welcome"
Instead a better, declarative example would be:
Given I have logged into the system
Then I should see "Welcome"
Use step.behave_as()
to call the imperative steps from your own step
abstracts the mechanics of your website into something more descriptive. This
also makes it easier if you ever change the login process.
@step("I have logged into the system")
def i_log_in():
'''Log in to the site'''
step.behave_as('Given I am on the login page')
step.behave_as('When I fill in "username" with "ABC"')
step.behave_as('And I fill in "password" with "XYZ"')
step.behave_as('And I checked the "Remember Me" checkbox')
step.behave_as('And I click on the "Submit" button')
step.behave_as('Then I should log into the system')
Step Writing Utilities¶
Aloe-Webdriver includes several utilities for writing Selenium tests.
-
class
aloe_webdriver.util.
ElementSelector
(browser, xpath=None, elements=None, filter_displayed=False, filter_enabled=False)¶ A set of elements on a page matching an XPath query.
Parameters: Delays evaluation to batch the queries together, allowing operations on selectors (e.g. union) to be performed first, and then issuing as few requests to the browser as possible.
One of xpath or elements must be passed. Passing xpath creates a selector delaying evaluation until it’s needed, passing elements stores the elements immediately.
Can behave as an iterable of elements or a single element by proxying all method calls, asserting that there is only one element selected.
Can be combined using the addition operator (
+
) to OR XPath queries together.-
evaluated
¶ Whether the selector has already been evaluated.
-
filter
(displayed=False, enabled=False)¶ Filter elements by visibility and enabled status.
Parameters: - displayed – whether to filter out invisible elements
- enabled – whether to filter out disabled elements
Returns: an
ElementSelector
-
-
aloe_webdriver.util.
element_id_by_label
(browser, label)¶ The ID of an element referenced by a label`s ``for` attribute. The label must be visible.
Parameters: - browser –
world.browser
- label – label text to return the referenced element for
Returns:
for
attribute value- browser –
-
aloe_webdriver.util.
find_any_field
(browser, field_types, field_name)¶ Find a field of any of the specified types.
Parameters: - browser –
world.browser
- field_types (list) – a list of field type (i.e. button)
- value (string) – an id, name or label
Returns: an
ElementSelector
See also:
find_field()
.- browser –
Find a button with the given value.
Searches for the following different kinds of buttons:
<input type=”submit”> <input type=”reset”> <input type=”button”> <input type=”image”> <button> <{a,p,div,span,…} role=”button”>Returns: an
ElementSelector
-
aloe_webdriver.util.
find_field
(browser, field_type, value)¶ Locate an input field.
Parameters: - browser –
world.browser
- field_type (string) – a field type (i.e. button)
- value (string) – an id, name or label
This first looks for value as the id of the element, else the name of the element, else as a label for the element.
Returns: an
ElementSelector
- browser –
-
aloe_webdriver.util.
find_field_by_id
(browser, field_type, id)¶ Locate the control input with the given
id
.Parameters: - browser –
world.browser
- field_type (string) – a field type (i.e. button)
- id (string) –
id
attribute
Returns: an
ElementSelector
- browser –
-
aloe_webdriver.util.
find_field_by_label
(browser, field_type, label)¶ Locate the control input that has a label pointing to it.
Parameters: - browser –
world.browser
- field_type (string) – a field type (i.e. button)
- label (string) – label text
This will first locate the label element that has a label of the given name. It then pulls the id out of the ‘for’ attribute, and uses it to locate the element by its id.
Returns: an
ElementSelector
- browser –
-
aloe_webdriver.util.
find_field_by_name
(browser, field_type, name)¶ Locate the control input with the given
name
.Parameters: - browser –
world.browser
- field_type (string) – a field type (i.e. button)
- name (string) –
name
attribute
Returns: an
ElementSelector
- browser –
-
aloe_webdriver.util.
find_field_by_value
(browser, field_type, name)¶ Locate the control input with the given
value
. Useful for buttons.Parameters: - browser –
world.browser
- field_type (string) – a field type (i.e. button)
- name (string) –
value
attribute
Returns: an
ElementSelector
- browser –
-
aloe_webdriver.util.
string_literal
(content)¶ Choose a string literal that can wrap our string.
If your string contains a
'
the result will be wrapped in"
. If your string contains a"
the result will be wrapped in'
.Cannot currently handle strings which contain both
"
and'
.
-
aloe_webdriver.util.
wait_for
(func)¶ A decorator to invoke a function, retrying on assertion errors for a specified time interval.
Adds a kwarg timeout to func which is a number of seconds to try for (default 15).