Data Driven in Automated Testing

DDT

DDT can be used when the testing framework is unittest. The ddt class decorator must be decorated on the subclass of TestCase. TestCase is a base class in the unittest framework, which implements the interface (interface) required by the Test Runner to drive the test to run.

The steps to use DDT are as follows:

  • Decorate your test class with @ddt;

  • Use @data or @file_data to decorate your data-driven test methods;

  • If a set of test data has multiple parameters, you need to unpack, use @unpack to decorate your test method.

Installation: pip install ddt

Acceptable data formats for ddt.data():

A set of data, each data is a single value; multiple sets of data, each set of data is a list or a dictionary

ddt provides data directly

single parameter


@ddt
class TestDdt(unittest.TestCase):
    @data("Tom","Jack")
    def test_a(self,a):
        print("这次的测试数据是"+a)
if __name__ == '__main__':
    unittest.main()

multiple parameters

  1. # data indicates that data is provided directly.

  2. # unpack means that for each set of data, if its value is list or tuple, it will be split into independent parameters.

@ddt
class TestDdt(unittest.TestCase):
    @data(["Tom1","Tom2"],["Jack1","Jack2"])
    @unpack
    def test_a(self,a,b):
        print("这次的测试数据是"+a+b)
if __name__ == '__main__':
    unittest.main()

 

 Use functions to provide data

 

import unittest

from ddt import ddt, data, unpack

def get_test_data():
    data=(["Tom1","Tom2"],["Jack1","Jack2"])
    return data

@ddt
class TestDdt(unittest.TestCase):
    @data(*get_test_data())
    @unpack
    def test_a(self,a,b):
        print("这次的测试数据是"+a+b)
if __name__ == '__main__':
    unittest.main()

Provide data using files 

You can use json or yaml files to provide test data

New test_a.json

{
  "case1": {
    "a": "Tom",
    "b":"Jack"
  },
  "case2": {
    "a": "Tom2",
    "b":"Jack2"
  }
}
import unittest

from ddt import ddt, data, unpack, file_data


@ddt
class TestDdt(unittest.TestCase):
    @file_data('test_a.json')
    def test_a(self,a,b):
        print("这次的测试数据是"+a+b)
if __name__ == '__main__':
    unittest.main()

Note that the test function here should be decorated with @file_data. Use external file method to load data without using unpack

use yaml file

pip install pyyaml
​​new test_a.yml

"case1":
  "a": "Tom1"
  "b": "Jack1"
"case2":
  "a": "Tom2"
  "b": "Jack2"

test_demo.py

import unittest

from ddt import ddt, data, unpack, file_data


@ddt
class TestDdt(unittest.TestCase):
    @file_data('test_a.yml')
    def test_a(self,a,b):
        print("这次的测试数据是"+a+b)
if __name__ == '__main__':
    unittest.main()

 

 Other format files

ddt only supports data in JSON and YAML formats by default. But what if I want to use other data formats?

There are two commonly used methods:

  • First read files in other formats (such as Excel format), then create a JSON or YAML file supported by ddt, and finally write the obtained data into this file, and then use @file_data();

  • Create a function, read files in other formats and get the data in the function, and return the data directly to the format supported by @ddt.data().

Parametrize

If you are using pytest, you can take this approach to be data driven.

pytest can be driven by data through pytest.mark.parametrize, and the data format requirements accepted by pytest.mark.parametrize are:

  • If there is only one set of data, it exists in the form of a list; note that parameters need to be passed in.

import pytest


@pytest.mark.parametrize('a',["Tom","Jack"])
def test_a(a):
    print("这次的测试数据是"+a)

输出:
PASSED                                         [ 50%]这次的测试数据是Tom
PASSED                                        [100%]这次的测试数据是Jack
  • If there are multiple sets of data, it exists in the form of nested tuples of lists (such as [0,1] or [(0,1), (1,2)]) (remarks, nested lists of actual lists can also be used)

import pytest


@pytest.mark.parametrize('a,b',[("Tom","Jack"),("Tom1","Jack1")])
def test_a(a,b):
    print("这次的测试数据是"+a+b)
输出PASSED                              [ 50%]这次的测试数据是TomJack
PASSED                                  [100%]这次的测试数据是Tom1Jack1

Provide data using yaml/json files

You can use json/yaml files to provide data, but you need to write a method to parse the corresponding data.

Because the data read by json and yaml are dictionaries nested dictionaries, so write a method to judge the file type using different modules to load, and the processing logic is the same.

import json
import os.path

import pytest
import yaml
def yaml_data(filename):
    file_path=os.path.abspath(filename)
    print(file_path)

    with open(filename,"r") as f:
        if file_path.endswith((".yml", ".yaml")):
            data=yaml.load(f,Loader=yaml.FullLoader)
        elif file_path.endswith(("json")):
            data=json.load(f)
        else:
            print("文件类型错误,仅支持yaml和json")
            raise
    result=[]
    for key,value in data.items():
        case_data = []
        for k,v in value.items():
            case_data.append(v)
        result.append(tuple(case_data))

    return result

@pytest.mark.parametrize('a,b',yaml_data(r'F:\接口自动化\pytest-auto-api2\test_a.json'))
def test_a(a,b):
    print("这次的测试数据是"+a+b)

Provide data using Excel files

Define a method to read data from excel, and both methods can be used here.

import openpyxl
def read_excel_data(filename,sheetname):
    if not os.path.exists(filename):
        raise ValueError("File not exists")
    workbook = openpyxl.load_workbook(filename)
    worksheet = workbook.get_sheet_by_name(sheetname)
    datas = list(worksheet.iter_rows(values_only=True))  # 获取Excel表中的所有数据,每一行组成元组,整个数据组成列表
    case_datas = datas[1:]  # 获取表数据
    cases_list = []
    for case in case_datas:
        cases_list.append(case)
    return cases_list


def read_excel_data2(filename, sheetname):
    workbook = openpyxl.load_workbook(filename)
    cases_list = []
    worksheet = workbook.get_sheet_by_name(sheetname)
    for row in worksheet.rows:
       cases_list.append([col.value for col in row])
    return cases_list[1:]


@pytest.mark.parametrize('a,b',read_excel_data(r'C:\Users\Administrator\Desktop\test1.xlsx','Sheet1'))
def test_a(a,b):
    print("这次的测试数据是"+a+b)

pandas

import pandas as pd
def read_excel_data3(filename,sheetname):
    s = pd.ExcelFile(filename)
    data =s.parse(sheet_name =sheetname)
    return data.values.tolist()

Guess you like

Origin blog.csdn.net/seanyang_/article/details/132055714