栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【Python自动化测试16】测试用例数据分离

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Python自动化测试16】测试用例数据分离

文章目录

一、前言

二、什么是数据分离?
三、进行数据分离
四、Python操作excel

一、前言

  本文章主要讲解Python自动化测试中测试用例的数据分离,在自动化测试中能够更好的管理测试用例以及代码,除此之外下方有系列文章的传送门,还在持续更新中,感兴趣的小伙伴也可以前往查看,话不多说,让我们一起看看吧~

系列文章:
  系列文章1:【Python自动化测试1】遇见Python之美
  系列文章2:【Python自动化测试2】Python安装配置及PyCharm基本使用
  系列文章3:【Python自动化测试3】初识数据类型与基础语法
  系列文章4:【Python自动化测试4】字符串知识总结
  系列文章5:【Python自动化测试5】列表与元组知识总结
  系列文章6:【Python自动化测试6】字典与集合知识总结
  系列文章7:【Python自动化测试7】数据运算符知识合集
  系列文章8:【Python自动化测试8】流程控制语句讲解
  系列文章9:【Python自动化测试9】函数知识合集
  系列文章10:【Python自动化测试10】文件基础操作
  系列文章11:【Python自动化测试11】模块、包与路径知识合集
  系列文章12:【Python自动化测试12】异常处理机制知识合集
  系列文章13:【Python自动化测试13】类、对象、属性与方法知识合集
  系列文章14:【Python自动化测试14】Python自动化测试基础与进阶练习题
  系列文章15:【Python自动化测试15】unittest测试框架的核心概念与作用

  

二、什么是数据分离?

  如下代码所示,在测试一个函数时我们需要编写测试用例并断言,通过框架及相关方法来进行测试,这样做会产生一个问题,对于一个庞大的软件、游戏而言,可能会有上万条测试用例,如果数据与代码存在绑定关系,很明显会有很多弊端,例如查询、更改测试数据等,这意味着代码和测试数据将会一起进行维护,维护成本会随着时间以及数量不断的增加,且有互相依赖性。
   故此我们需要把数据与代码区分开来,那么分开的这个过程和结果,我们就称之为数据分离,进行单独性的管理。 那么测试用例的数据分离,就是将用例数据与代码区分开的意思。如果测试数据需要进行修改或添加,那么我们只需要维护测试数据即可,而测试用例是不需要进行改动的。

"""
一共涉及到4个知识内容:
1、setUp  测试用例前执行
2、teardown  测试用例后执行
3、setUpClass  测试类之前执行
4、teardownClass  测试类之后执行
"""
import unittest


def login(username=None, password=None):
    if username is None or password is None:
        return {"code": 400, "msg": "用户名或密码为空" }
    if username == "萌笑天" and password == 123456:
        return {"code": 200, "msg": "登录成功" }
    return {"code": 300, "msg": "用户名或密码错误" }


class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        """每个测试用例之前都会执行的代码"""
        print("每个测试用例之前的准备工作")
        print("假装正在连接数据库...")

    def tearDown(self) -> None:
        """每个测试用例之后都会执行的代码,无论测试用例是否通过,tearDown均会执行"""
        print("每个测试用例执行之后都需要做的事情")
        print("假装正在断开数据库")

    @classmethod
    def setUpClass(cls) -> None:
        """每个测试类之前都会执行的"""
        print("每个测试类之前只执行一次")

    @classmethod
    def tearDownClass(cls) -> None:
        """每个测试类之后都会执行的"""
        print("每个测试类之后会执行一次")

    def test_login_success(self):
        username = "萌笑天"
        password = 123456
        expected = {"code": 200, "msg": "登录成功"}
        actual = login(username,password)
        self.assertEqual(expected, actual)  # 断言预期结果与实际结果是否相等

    def test_login_error(self):
        username = "萌笑天"
        password = 1234567
        expected = {"code": 1100, "msg": "用户名或密码错误" }
        actual = login(username,password)
        self.assertEqual(expected, actual)

  

三、进行数据分离

  进行数据分离的核心就是将数据与代码分开,结合我们前面所学的知识,我们可以把一些测试数据以列表嵌套字典的形式进行存储,转化后的代码为:

"""
TODO:请注意,下面的这些代码并非是最佳的优化途径,只是为了在配合数据分离的知识内容进行讲解
TODO:在后续会逐渐进行优化,采取更优策略,后续文章会进行说明
"""
import unittest

login_data = [
    {"username": "萌笑天", "password": 123456, "expected": {"code": 200, "msg": "登录成功"}},
    {"username": "萌笑天", "password": 1234567, "expected": {"code": 1100, "msg": "用户名或密码错误"}}
]

def login(username=None, password=None):
    if username is None or password is None:
        return {"code": 400, "msg": "用户名或密码为空" }
    if username == "萌笑天" and password == 123456:
        return {"code": 200, "msg": "登录成功" }
    return {"code": 300, "msg": "用户名或密码错误" }


class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        """每个测试用例之前都会执行的代码"""
        print("每个测试用例之前的准备工作")
        print("假装正在连接数据库...")

    def tearDown(self) -> None:
        """每个测试用例之后都会执行的代码,无论测试用例是否通过,tearDown均会执行"""
        print("每个测试用例执行之后都需要做的事情")
        print("假装正在断开数据库")

    @classmethod
    def setUpClass(cls) -> None:
        """每个测试类之前都会执行的"""
        print("每个测试类之前只执行一次")

    @classmethod
    def tearDownClass(cls) -> None:
        """每个测试类之后都会执行的"""
        print("每个测试类之后会执行一次")

    def test_login_success(self):
        data = login_data[0]
        username = data["username"]
        password = data["password"]
        expected = data["expected"]
        actual = login(username,password)
        self.assertEqual(expected, actual)

    def test_login_error(self):
        data = login_data[1]
        username = data["username"]
        password = data["password"]
        expected = data["expected"]
        actual = login(username,password)
        self.assertEqual(expected, actual)

  
  如上代码所示,目前测试数据和代码是实现了分离,这样当我们想进行测试数据维护或代码维护时就会更加便捷,虽然这样的方式并不是最有效的,但主要是为了让大家先行理解数据分离的概念,将会在后续的文章中继续进行优化。
  正常而言我们要进行模块管理,即代码属于一个模块(py文件),而数据属于一个模块,故此我们实际的data数据并不是放在代码模块中的,而应该是一个新的data.py的模块文件,通过导入的方式进行调用,真实的项目里亦是如此,如上代码是方便新手进行理解所用:

E:TestingSoftwarePython3.10.1(64x)python.exe "E:TestingSoftwarePyCharmPyCharm Community Edition 2021.3pluginspython-cehelperspycharm_jb_unittest_runner.py" --target test_login.TestLogin.test_login_error
Testing started at 10:49 ...
Launching unittests with arguments python -m unittest test_login.TestLogin.test_login_error in E:TestingSoftwarePython3.10.1(64x)PythonProjectCSDN自动化测试系列_第一节_Python基础语法1

每个测试类之前只执行一次
每个测试用例之前的准备工作
假装正在连接数据库...
每个测试用例执行之后都需要做的事情
假装正在断开数据库


{'code': 300, 'msg': '用户名或密码错误'} != {'code': 1100, 'msg': '用户名或密码错误'}

Expected :{'code': 1100, 'msg': '用户名或密码错误'}
Actual   :{'code': 300, 'msg': '用户名或密码错误'}


Traceback (most recent call last):
  File "E:TestingSoftwarePython3.10.1(64x)PythonProjectCSDN自动化测试系列_第一节_Python基础语法1test_login.py", line 55, in test_login_error
    self.assertEqual(expected, actual)
AssertionError: {'code': 1100, 'msg': '用户名或密码错误'} != {'code': 300, 'msg': '用户名或密码错误'}
- {'code': 1100, 'msg': '用户名或密码错误'}
?          ^^

+ {'code': 300, 'msg': '用户名或密码错误'}
?          ^




每个测试类之后会执行一次


Ran 1 test in 0.005s

FAILED (failures=1)

Process finished with exit code 1




  

四、Python操作excel
"""
数据分离的流程:
1、excel编写测试用例
2、通过Python读取excel(读取出来的格式就是列表嵌套字典: [{}, {}, {}]
3、导入测试用例函数

由上得知:目前只需要有一份excel版本的测试用例,并通过Python读取即可
"""

  在路径下创建一个case.xlsx,存储测试用例数据

  openpyxl属于第三方库,故此我们需要先行安装,已经安装过会直接更新

  如下代码所示:我们用函数进行封装,使用openpyxl进行excel数据的读取

"""
Python操作excel的思路:
1、先打开excel文件
2、选择对应表格页签
3、读取对应单元格数据
4、通过数据实现一定的操作
5、关闭excel文件
"""
import openpyxl  # 专门用于处理excel表格的库,openpyxl拥有pandas的特性,并属于轻量级库,不会像pandas一样更加复杂,更具优势
from openpyxl.worksheet.worksheet import Worksheet


def read_excel(file_path, sheet_name ):
    """读取excel的函数"""
    workbook_data = openpyxl.load_workbook(file_path)  # 打开名称为case.xlsx的excel文档
    sheet: Worksheet = workbook_data[sheet_name]  # 页签名为login,定位到login页签,指明sheet类型为Worksheet

    # """如果我们想要获取某一个单元格的数据,可以使用这个方式,但往往一个表格中有庞大的数据,我们并非通过这样的方式获取"""
    # cell = sheet.cell(row=1, column=1)  # 获取单元格数据,row为行,column为列,代码中表示的为第一行第一列的单元格
    # print(cell.value)  # 获取第一行第一列的数据

    """更推荐的获取方法是获取所有数据,因为获取的数据并非列表类型,我们还需要进一步进行数据转换"""
    values = list(sheet.values)
    workbook_data.close()  # 关闭文件

    return values

data = read_excel("case.xlsx", "login")
print(data)

  在之前提及过,测试用例的数据是列表嵌套字典的形式,而打印的数据则是列表嵌套元组的形式,并不符合预期,所以还需要进一步的转换:

"""
Python操作excel的思路:
1、先打开excel文件
2、选择对应表格页签
3、读取对应单元格数据
4、通过数据实现一定的操作
5、关闭excel文件
"""
import openpyxl  # 专门用于处理excel表格的库,openpyxl拥有pandas的特性,并属于轻量级库,不会像pandas一样更加复杂,更具优势
from openpyxl.worksheet.worksheet import Worksheet


def read_excel(file_path, sheet_name ):
    """读取excel的函数"""
    workbook_data = openpyxl.load_workbook(file_path)  # 打开名称为case.xlsx的excel文档
    sheet: Worksheet = workbook_data[sheet_name]  # 页签名为login,定位到login页签,指明sheet类型为Worksheet

    # """如果我们想要获取某一个单元格的数据,可以使用这个方式,但往往一个表格中有庞大的数据,我们并非通过这样的方式获取"""
    # cell = sheet.cell(row=1, column=1)  # 获取单元格数据,row为行,column为列,代码中表示的为第一行第一列的单元格
    # print(cell.value)  # 获取第一行第一列的数据

    """更推荐的获取方法是获取所有数据,因为获取的数据并非列表类型,我们还需要进一步进行数据转换"""
    values = list(sheet.values)
    workbook_data.close()  # 关闭文件
    title = values[0]
    rows = values[1:]
    new_rows = [dict(zip(title, row)) for row in rows]
    return new_rows

data = read_excel("case.xlsx", "login")
print(data)


  
  

  好啦~以上就是本次文章分享的全部内容啦,你学会了吗?希望能给大家带来帮助哦!

  
  

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/738833.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号