07-数据驱动(unittest ddt)

一、数据驱动ddt

ddt说明

ddt即data-driver test,数据驱动测试。 以数据来驱动整个测试用例的执行(即测试数据决定测试结果)。可以和unitttest结合实现数据驱动。

数据驱动解决的问题

1)代码和数据分离,避免代码冗余
2)不写重复的代码逻辑;

安装ddt

在cmd打开的黑窗口中输入pip install ddt即可安装

语法说明

@ddt 装饰类,作用是用于申明当前类使用ddt数据驱动。
@data 装饰函数,作用是给函数传值。
@unpack 装饰函数,作用是数据解包。
@file_data 装饰函数,作用是直接读取yaml、json文件。

使用方法

1、使用数据驱动,要在class前加上修饰器 @ddt

import unittest
from ddt import ddt, data

@ddt  
class TestDemo(unittest.TestCase):
    # 单一参数
    @data('17611110000', '17611112222')
    def test_1(self, phone):
    	# 此处输入测试用例代码
        print('测试一电话号码:', phone)
        
if __name__ == '__main__':
    unittest.main()
else:
    pass

结合 selenium 使用 ddt

"""
unittest + selenium
"""
import unittest
from time import sleep

from ddt import ddt, data
from selenium import webdriver

@ddt
class TestBaidu(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('https://www.sogou.com/')

    def tearDown(self) -> None:
        sleep(3)
        self.driver.quit()
	
    # 单一参数
    @data('易烊千玺', '王嘉尔')
    def test_01(self, name):
        self.driver.find_element_by_id('query').send_keys(name)
        self.driver.find_element_by_id('stb').click()

if __name__ == '__main__':
    unittest.main()

self: 相当于java中的this,当前对象的引用,self.driver定义了driver这个变量。

2、多个参数传参:
注意事项:

1)多个数据传参的时候@data里面是要用列表形式
2)会用到 @unpack 装饰器 进行拆包,把对应的内容传入对应的参数;

import unittest
from ddt import ddt, data, unpack

@ddt
class TestDemo(unittest.TestCase):
    # 多参数数据驱动
    @data(['admin', '123456'])
    # unpack 是进行拆包,不然会把列表里面的数据全部传到username这个一个参数,我们要实现列表中的两个数据分别传入对应的变量中
    @unpack
    def test_2(self, username, password):
        print('测试二:', username, password)


if __name__ == '__main__':
    unittest.main()
else:
    pass

但是以上步骤都是数据在代码当中的,假如要测试n个手机号这样的数据,全部写在 @data 装饰器里面就很麻烦,这就引出了数据驱动里面的代码和数据的分离。

3、将数据放入一个文本文件中,从文件读取数据, 如json、 excel、 xml、 txt等格式文件。

二、数据文件驱动

1、在json文件驱动

json文件:

[
  {
    "username": "admin",
    "password": "123456"
  },
  {
    "username": "normal",
    "password": "45678"
  }
]

读取json文件:

import json
import unittest
from ddt import ddt, data, unpack


# 用json多个参数读取
def reads_phone():
    with open('user.json', encoding='utf-8') as f:
        result = json.load(f)  # 列表
        return result
    
@ddt
class TestDemo(unittest.TestCase):
    # 多参数数据驱动
    @data(*reads_phone())
    # unpack 是进行拆包,不然会把列表里面的数据全部传到username这个一个参数,我们要实现列表中的两个数据分别传入对应的变量中
    @unpack
    def test_2(self, username, password):
        print('测试二:', username, password)


if __name__ == '__main__':
    unittest.main()
else:
    pass

注意事项:

1with open里面默认是 ”r“ 
2、@data 里面的 * 含义是实现每个json对象单个传入方法执行,不然会吧json文件里面所用数据全部传入 
	> * 是元祖;
	> ** 是字典;
3、参数不能传错,要对应

执行结果:
在这里插入图片描述

2、txt文件驱动

txt文件:一行表示一组

admin,123456
normal,456789

代码:

import unittest
def read():
    lis = []
    with open('readtext.txt', 'r', encoding='utf-8') as f:
        for line in f.readlines():
            # lis.append(line) #  ['admin,123456\n', 'normal,456789\n']
            # lis.append(line.strip('\n'))  ['admin,123456', 'normal,456789'] 两个字符串
            lis.append(line.strip('\n').split(','))  # [['admin', '123456'], ['normal', '456789']]
    return lis

class TestDome(unittest.TestCase):
    def test_01(self):
        li = read()
        print(li)


if __name__ == '__main__':
    unittest.main()

注:

split():一个字符串里面用某个字符分割,返回列表
strip():去掉两边的字符或者字符串,默认删除空白符(包括'\n', '\r',  '\t',  ' ')

3、csv文件驱动

csv文件:

供应商名称,联系人,移动电话
英业达,张三,13261231234
阿里巴巴,李四,13261231231
日立公司,王五,13261231233

写法一:

"""
编写 csvv.py脚本读取csv中的测试数据
"""
import csv
class ReadCsv():
    def read_csv(self):
        lis = []
        # 用csv的API的reader方法!!!!
        data = csv.reader(open('testdata.csv', 'r'))  #!!!!
        next(data, None)
        for line in data:
            lis.append(line)
            # lis.append(line[0])  # 二维数组可以省略行,列不可以省略
            # lis.append(line[1])

        return lis

# 实例化类
readCsv = ReadCsv()
# 打印类中的方法
print(readCsv.read_csv())

在这里插入图片描述

写法二: 推荐def csvTest():

li = []
with open('user.csv', 'r', encoding='utf-8') as f:
    filename = csv.reader(f)
    next(filename, None)
    for r in filename:
        li.append(r)
    return li

4、yaml文件驱动

yaml文件:

-
  username: admin9
  password: 123456
-
  username: normal
  password: 789456

对应的json文件:

[
  {
    "username": "admin9",
    "password": 123456
  },
  {
    "username": "normal",
    "password": 7894
  }
]

写法:

import unittest
from time import sleep

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

@ddt
class YamlTest(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('file:///D:/%E6%A1%8C%E9%9D%A2/page/%E6%B3%A8%E5%86%8CA.html')
        self.driver.maximize_window()

    def tearDown(self) -> None:
        driver = self.driver
        sleep(3)
        driver.quit()

    # file_data 传入多个参数的时候,@unpack 的解包不起作用
    @unittest.skip
    @file_data('../user.yaml')
    @unpack
    def test_yaml01(self, username, password):
        driver = self.driver
        driver.find_element_by_id('userA').send_keys(username)
        driver.find_element_by_id('passwordA').send_keys(password)

    # 注意:传的参数名称要与yaml文件对应
    # 在yaml数据中文件中采用对象(键值对)的方式来定义数据内容
    @file_data('../user1.yaml')
    def test_yaml02(self, username, password):
        driver = self.driver
        driver.find_element_by_id('userA').send_keys(username)
        driver.find_element_by_id('passwordA').send_keys(password)


if __name__ == '__main__':
    unittest.main()

**注:**file_date 装饰器,可以直接读取yaml和json文件

5、Excel文件驱动

建立excel表的时候需要退出pychram在根目录下创建excel表保存,否则会报错。
示例: 用excel登录csdn操作

"""
测试excel数据驱动
"""

import unittest
from time import sleep

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


# 读取excel表中的数据,使用xlrd,openpyxl
def read_excel():
    xlsx = openpyxl.load_workbook("../excel.xlsx")
    sheet1 = xlsx['Sheet1']
    print(sheet1.max_row)  # 行
    print(sheet1.max_column)  # 列
    print('=======================================================')
    allList = []
    for row in range(2, sheet1.max_row + 1):
        rowlist = []
        for column in range(1, sheet1.max_column + 1):
            rowlist.append(sheet1.cell(row, column).value)
        allList.append(rowlist)
    return allList


@ddt
class ExcelText(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('https://passport.csdn.net/login?code=applets')
        self.driver.maximize_window()

    def tearDown(self) -> None:
        driver = self.driver
        sleep(3)
        driver.quit()

    @data(*read_excel())
    @unpack
    def test_excel01(self, flag, username, password):
        print(flag, username, password)
        driver = self.driver
        sleep(2)
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[1]/span[4]').click()
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[2]/div/div[1]/div/input').send_keys(username)
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[2]/div/div[2]/div/input').send_keys(password)
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[2]/div/div[4]/button').click()

if __name__ == '__main__':
    unittest.main()
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值