BDD Testing. What Tools Are There & Examining One of Them
Przemysław Pliński
Senior Automation Engineer
Aleksander Jess
Senior Content Marketer & Technical Expert
Rafał Korzeniewski
Python Developer
Quality Assurance (QA)
Software Development
Behavior Driven Development (BDD) Framework gives testers the possibility to create test scripts in plain English (or other natural language). Due to the use of natural language to describe test cases, the preparation of some of them may lie on the side of the business. It can also be, for example, a form of describing business requirements. So here we have space for closer cooperation between teams and an opportunity to save time needed to write acceptance tests. BDD’s focus is the behavior of the user. There are many tools to develop BDD test frameworks: pytest-bdd, Cucumber, Quantum, JBehave, behave, radish. In here we will focus on pytest-bdd which powerful python based BDD tool.
[P]ytest-bdd implements a subset of the Gherkin language to enable automating project requirements testing and to facilitate behavioral driven development.
[P]ytest-bdd is a pytest framework plugin, so it doesn't need an individual runner. Its developers emphasize that their tool takes advantage of the power and versatility of pytest. They also guarantee that it allows for combining unit and functional tests, lessens the stress of setting up a continuous integration server, and enables reuse of test setups.
Let's try to list some advantages and disadvantages of this solution.
Pros
It is compatible with pytest and most of the pytest plugins.
Fixtures created for pytest unit tests can be used again for the setup and actions described in feature steps, with the injection of dependencies.
Pytest community is huge
Can be executed along with other pytest tests
Handles tabular data for better data-driven testing.
A lot of online docs and training resources
Is supported by PyCharm IDE and Visual Studio Code
Cons
First, it is worth noting that the BDD methodology itself has some disadvantages. Especially when it is used contrary to its intended purpose.
For example, this approach may require quite a lot of additional work, including additional meetings of business representatives, developers and testers
BDD should be applied in the case of User Acceptance Tests, where the actor has the appropriate knowledge and is able to implement complex scenarios even manually. Because of its link to the user behavior, this approach may not be appropriate for system, integration, or unit testing.
Requires additional code needed to declare scenarios, implement scenario outlines, and provide steps.
Example implementation with Selenium Webdriver
As an example, we will implement a solution for WebUI tests, using pytest-bdd, Selenium Webdriver and a sample website https://www.saucedemo.com/
As you can see, after entering website https://www.saucedemo.com/ we can log in. If you wish to give it a try, working credentials are: standard_user / secrect_sauce.
After a successful login, the application redirects us to a shop site (https://www.saucedemo.com/inventory.html ) where we can see list of products:
Let’s say, we want to automate a test procedure in which we log in and then check if after successful login there is a page with “PRODUCTS” inside the header. This element is inside the HTML span tag with class=”title”.
Products
Since we performed the manual test setup, it’s now time to do some automation. In that case, we will do it with pytest-bdd.
Step 1: Prerequisites
IDE of your choice (PyCharm integrates with pytest-bdd, therefore it is the preferred choice)
Python installed on your machine
Chrome browser installed
Step 2: Install Required Libraries
Create python virtual environment, below command will create virtual env in current directory:
python3 -m venv .
Activate virtual env:
source Scripts/activate
Install pytest-bdd, selenium and webdriver-manager
features/login.feature - Steps for the scenario are written in feature files
Feature: Login
Login page scenario
Scenario Outline: Login With Correct Credentials
Given Login page
When I type <username> <password> and click login
Then I should be logged in
Examples:
| username | password |
| standard_user | secret_sauce |
conftest.py - this file is used to store pytest fixtures, for our simple setup we will need only one fixture that will initialize WebDriver and close it after test is done
import pytest from selenium
import webdriver from selenium.webdriver.chrome.service
import Service as ChromeService from webdriver_manager.chrome
import ChromeDriverManager
@pytest.fixture(scope='function')
def init_driver():
web_driver = webdriver.Chrome(
service=ChromeService(
ChromeDriverManager().install()
)
)
yield web_driver
web_driver.close()
page_objects/base_page.py - base Class to build our POM model
from selenium import webdriver
class BasePage:
def __init__(self, driver: webdriver.Chrome):
self.driver = driver
page_objects/products_page.py - products page Class with method that will help us verify if we have been correctly logged in
from selenium.webdriver.common.by import By
from page_objects.base_page import BasePage
class Login(BasePage):
def go_to_login_page(self):
self.driver.get("https://www.saucedemo.com/")
def fill_form_and_log_in(self, username, password):
self.driver.find_element(By.ID, 'user-name').send_keys(username)
self.driver.find_element(By.ID, 'password').send_keys(password)
self.driver.find_element(By.ID, "login-button").click()
test_login.py - implementation of our scenario steps from login.feature file
from pytest_bdd import scenarios, given, when, then, parsers
from selenium import webdriver
from page_objects.login_page import Login
from page_objects.products_page import Products
scenarios("../features/login.feature")
@given(parsers.parse("Login page"), target_fixture="login_page")
def open_login_page(init_driver: webdriver.Chrome):
page = Login(init_driver)
page.go_to_login_page()
return page
@when(parsers.parse("I type {username} {password} and click login"))
def log_in(login_page: Login, username: str, password: str):
login_page.fill_form_and_log_in(username, password)
@then("I should be logged in")
def verify_login(init_driver: webdriver.Chrome):
title = Products(init_driver).get_title()
assert "PRODUCTS" == title
Step 5: Running tests
Running pytest tests is quite simple, we can trigger tests by one command:
pytest tests/
Or even simpler:
pytest
Where $ is a prompt of terminal, and we call pytest in main project directory
After that our browser should open, code should perform all our scenario steps and present results in the console.
=================== test session starts ===================
platform darwin -- Python 3.10.7, pytest-7.2.0, pluggy-1.0.0
rootdir: /Users/rkorzen/PycharmProjects/pytest_BDD_example
plugins: bdd-6.1.1
collected 1 item
tests/test_login.py . [100%]
==================== 1 passed in 3.75s ====================
There is also good integration with pycharm IDE. We can run tests from IDE directly. That is the result:
Conclusion
Implementing BDD Framework Using pytest-bdd is extremely easy and should not be a problem for QA Engineers with some programming experience. Such a solution is a perfect link between QAs, Developers and Business Stakeholders. The feature files can be read and understood by everybody and at the same time, gives QA’s power and flexibility in the creation of test code using the pytest framework. It’s one of the best python testing frameworks out there.
360° IT Check is a weekly publication where we bring you the latest and greatest in the world of tech. We cover topics like emerging technologies & frameworks, news about innovative startups, and other topics which affect the world of tech directly or indirectly.
Like what you’re reading? Make sure to subscribe to our weekly newsletter!
Relevant Expertise:
No items found.
Share
Subscribe for your monthly dose of tech news
Thank you! Your submission has been received! We will send you at most one email per week with our latest tech news and insights.
In the meantime, feel free to explore this page or our Resources page for eBooks, technical guides, GitHub Demos, and more!
Oops! Something went wrong while submitting the form.
Join 17,850 tech enthusiasts for your weekly dose of tech news
Thank you! Your submission has been received! We will send you at most one email per week with our latest tech news and insights.
In the meantime, feel free to explore this page or our Resources page for eBooks, technical guides, GitHub Demos, and more!
Oops! Something went wrong while submitting the form.