DDT with Python Selenium

DDT (Data-driven Testing) with Python Selenium Webdriver is very easy! DDT becomes very useful if you have test cases that contains the same test steps. All values could outsourced into files or databases. This tutorial use CSV files.

Precondition

  • Python installed
  • selenium and ddt library installed

Example

The folder structure for this tutorial looks like:

├── data
│   └── scenario_a.csv
├── library
│   ├── GetData.py
│   └── __init__.py
├── scenarios
│   ├── __init__.py
│   └── scenario_a.py
└── testsuite.py

Into folder “data” we store the csv files. The packages “library” include a function to read the specific csv files and the package “scenarios” include the test cases. The test suite is on root folder.

#!/usr/bin/env python
# -*- coding: utf8 -*-

import unittest

from scenarios.scenario_a import TestScenarioA


# load test cases
scenario_a = unittest.TestLoader().loadTestsFromTestCase(TestScenarioA)

# create test suite
test_suite = unittest.TestSuite([scenario_a])

# execute test suite
unittest.TextTestRunner(verbosity=2).run(test_suite)

Into the “testsuite.py” we add all test cases provided by scenario package.

data folder

target_url,elem_name,search_value
http://softwaretester.info,s,python
http://softwaretester.info,s,selenium
http://softwaretester.info,s,webdriver
http://softwaretester.info,s,automation

The CSV stores the test data that we supplied to the @data decorator of test case.

library package

#!/usr/bin/env python
# -*- coding: utf8 -*-

__author__ = 'lupin'
#!/usr/bin/env python
# -*- coding: utf8 -*-

import csv


def get_csv_data(csv_path):
    """
    read test data from csv and return as list

    @type csv_path: string
    @param csv_path: some csv path string
    @return list
    """
    rows = []
    csv_data = open(str(csv_path), "rb")
    content = csv.reader(csv_data)

    # skip header line
    next(content, None)

    # add rows to list
    for row in content:
        rows.append(row)

    return rows

Just for read the csv and return the values as a list.

scenarios package

#!/usr/bin/env python
# -*- coding: utf8 -*-

__author__ = 'lupin'
#!/usr/bin/env python
# -*- coding: utf8 -*-

import unittest

from selenium import webdriver
from ddt import ddt, data, unpack

from library.GetData import get_csv_data


@ddt
class TestScenarioA(unittest.TestCase):
    """ inheriting the TestCase class"""

    @classmethod
    def setUpClass(cls):
        """test preparation"""
        cls.driver = webdriver.Firefox()
        cls.driver.implicitly_wait(3)
        cls.driver.set_window_size(450, 500)

    @data(*get_csv_data('./data/scenario_a.csv'))
    @unpack
    def test_search(self, target_url, elem_name, search_value):
        """test case for scenario a"""
        driver = self.driver
        driver.get(target_url)

        btn_elem = driver.find_element_by_id('search-toggle')
        btn_elem.click()

        input_elem = driver.find_element_by_name(elem_name)
        input_elem.clear()
        input_elem.send_keys(search_value)
        input_elem.submit()

    @classmethod
    def tearDownClass(cls):
        """clean up"""
        cls.driver.close()

Test case with @ddt (for classes), @data and @unpack (for methods) decorators.

  • @data take the arguments from csv file
  • @unpack unpacks tuples or lists into multiple arguments

The test_search() method accepts the arguments, which will be mapped to the tuple values by ddt.

Run

$ python -B testsuite.py