BDD Testing. What Tools Are There & Examining One of Them
Table of Contents

BDD Testing. What Tools Are There & Examining One of Them

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.

Why pytest-bdd?

In the project documentation, we can read that:

[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

  1. IDE of your choice (PyCharm integrates with pytest-bdd, therefore it is the preferred choice)
  1. Python installed on your machine
  1. Chrome browser installed

Step 2: Install Required Libraries

  1. Create python virtual environment, below command will create virtual env in current directory:

python3 -m venv .

  1. Activate virtual env:

source Scripts/activate

  1. Install pytest-bdd, selenium and webdriver-manager
pip install pytest-bdd
pip install webdriver-manager 
pip install selenium 

Step 3: Create File Structure

Create required files and folders structure for further setup:


. 
├── features 
│   └── login.feature 
├── page_objects 
│   ├── base_page.py 
│   ├── login_page.py 
│   └── products_page.py 
├── tests 
│   └── test_login.py 
├── README.md 
├── conftest.py 
└── requirements.txt 

Step 4: Files Content

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.  

Liked the article? subscribe to updates!
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

Join 17,850 tech enthusiasts for your weekly dose of tech news

By filling in the above fields and clicking “Subscribe”, you agree to the processing by ITMAGINATION of your personal data contained in the above form for the purposes of sending you messages in the form of newsletter subscription, in accordance with our Privacy Policy.
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.

Related articles

Our Partners & Certifications
Microsoft Gold Partner Certification 2021 for ITMAGINATION
ISO-IEC 27001:2013 ITMAGINATION ISO 9001 ITMAGINATION
© 2024 ITMAGINATION, A Virtusa Company. All Rights Reserved.