用Excel表格编写用例的自动化测试框架

本文介绍了一个使用Excel表格维护UI自动化测试用例的框架。通过设计特定的用例模板,读取Excel内容并转化为Selenium操作,实现了用例的自动化生成、执行和恢复初始状态。该方法降低了用例编写的门槛,提高了测试框架的维护效率。

上次写的这个框架(如下),编写用例对编辑者的python能力有一定要求;用例如果是用Excel表格来维护,可以降低用例编写的门槛,可以增加这个自动化测试框架的维护效率。

selenium二次封装的步骤_python_problem的博客-优快云博客为一个比较复杂的系统写UI自动化时,需要考虑提高代码的复用率、各个页面测试用例的管理等方面,所以我们需要对代码进行封装。1.建立项目建立项目:com.baidu2.获取浏览器驱动在baidu文件夹下建立common文件夹,下面创建seleniumDriver.py文件,用于获取浏览器驱动3.集成setUp和tearDown函数在common文件夹下,创建myUnit.py文件,写入MyUnit类,用于集成setUp和tearDown两个函数;4.集成页面元素获取/页面截屏等方法.https://blog.youkuaiyun.com/python_problem/article/details/121848038?spm=1001.2014.3001.5501

目录

资源地址

思路整理

改造过程

1.设计用例模版

2.表格中内容的读取

3.字典数据转化为selenium操作

4.创建驱动文件

5.生成用例文件的方法

6.将用例加入测试套件的方法(用例执行文件)

7.执行运行文件的方法

8.恢复初始状态的方法

9.进行测试

框架的维护使用


资源地址

不想看详细的编写过程,着急使用的小伙伴,可点下方链接,内附了完整框架资源和使用文档

https://download.youkuaiyun.com/download/python_problem/72603388

思路整理

  1. 在Excel表格中写入用例,每个sheet页写一条完整的测试用例,每行写一条操作步骤;
  2. 将表格中的内容读取出来;
  3. 根据每条操作的描述转化成python语言的文件,方便测试用例文件进行调用;
  4. 把读取的内容根据每个sheet页转化为对应的测试用例文件;
  5. 把这些用例添加到执行文件里的测试套件中;
  6. 最后执行“执行文件”。

改造过程

1.设计用例模版

  • 序号/模块名称的填写需要与操作内容相符合
  • 操作名称列:同一操作,必须是约定好的唯一的名称,便于以后转换为selenium操作
  • 是否执行:填写yes/no,决定是否执行该操作,便于以后维护 
  • 元素定位方法:ID/ name/ class/ tagName/ linkText/ css/ xpath
  • 元素定位路径:根据元素定位方法写入对应的路径
  • 文本值:在输入值、判断等需要文本值的操作,填入对应文本
  • 等待时间:需要等待时可填入等待时间(若为隐式等待也可不写等待操作)

2.表格中内容的读取

import openpyxl


def dataRead(lujing="../data/测试用例模板.xlsx"):
    # 读取Excel
    excel = openpyxl.load_workbook(lujing)
    # 第一层字典 ------ 创建data空字典
    data = {}
    # 获取所有sheet页名称并进行遍历
    for sheet_name in excel.sheetnames:
        # 若sheet页名称包含test_case,就将这个sheet页赋给变量"sheet"
        if "test_case" in sheet_name:
            sheet = excel[sheet_name]
            # 第二层字典 ------ 在data字典中,创建以sheet页名称为键的空字典
            data[sheet_name] = {}
            # 获取所有行的数据,并进行遍历
            for row_data in sheet.rows:
                # 第三层字典 ------ 创建以操作序号为键的空字典
                data[sheet_name][row_data[0].value] = {}
                # 第四层字典 ------ 内容放入键值对
                data[sheet_name][row_data[0].value]['operation'] = row_data[2].value  # 操作名称
                data[sheet_name][row_data[0].value]['perform'] = row_data[3].value  # 是否执行
                data[sheet_name][row_data[0].value]['method'] = row_data[4].value  # 元素定位方法
                data[sheet_name][row_data[0].value]['path'] = row_data[5].value  # 元素定位路径
                data[sheet_name][row_data[0].value]['text'] = row_data[6].value  # 文本值
                data[sheet_name][row_data[0].value]['time'] = row_data[7].value  # 等待时间
                # 第一行为"序号"没有操作,需要移除;操作名称若为空没有操作,也需要移除
                if not isinstance(row_data[0].value, int):
                    data[sheet_name].pop(row_data[0].value)  # 移除表头
                elif data[sheet_name][row_data[0].value]['operation'] is None:
                    data[sheet_name].pop(row_data[0].value)  # 移除空操作
    # 返回字典
    return data

返回的字典数据为多个sheet页中的数据,格式如下:

{
    'test_case03': {
        1: {
            'operation': '打开浏览器',
            'perform': 'yes',
            'method': None,
            'path': None,
            'text': 'https://www.baidu.com',
            'time': None
        },
        2: {
            'operation': '输入',
            'perform': 'yes',
            'method': 'xpath',
            'path': '//*[@id="kw"]',
            'text': '萝卜',
            'time': None
        },
        ......
    },
    'test_case04': {
        1: {
            'operation': '打开浏览器',
            'perform': 'yes',
            'method': None,
            'path': None,
            'text': 'https://www.baidu.com',
            'time': None
        },
        ......
    }

}

3.字典数据转化为selenium操作

此处的“字典数据”为单个sheet页中的数据,格式如下:

{
        1: {
            'operation': '打开浏览器',
            'perform': 'yes',
            'method': None,
            'path': None,
            'text': 'https://www.baidu.com',
            'time': None
        },
        2: {
            'operation': '输入',
            'perform': 'yes',
            'method': 'xpath',
            'path': '//*[@id="kw"]',
            'text': '萝卜',
            'time': None
        },
        ......
}

字典数据转化为selenium操作的代码如下: 

import time
from com.baidu.common.myUnit import MyUnit
from com.baidu.pageObject.pageObject import PageObject
from selenium.webdriver import ActionChains  # 鼠标事件
from com.baidu.pages.dataRead import dataRead   # 读取表格内容的方法


class DataPerform(PageObject):

    # 将读取内容转化为selenium操作
    def data_perform(self, case01):
        # 创建空列表,用于存储判断结果
        check_results = []
        # 遍历数据并获取键名称(操作序号)
        for operation_code in case01:
            # 按照操作序号获取每一条操作数据
            case02 = case01[operation_code]
            # 是否执行为yes,才执行操作
            if case02['perform'] == 'yes':
                # 根据操作名称,执行对应的操作
                if case02['operation'] == '打开浏览器':
                    self.driver.get(case02['text'])

                elif case02['operation'] == '条件等待':
                    if case02['method'] == 'xpath':
                        percents = self.driver.find_element_by_xpath(case02['path'])  # 加载进度
                        i = 1
                        while percents.text != case02['text']:
                            time.sleep(1)
                            if i == 90:  # 最多等待20秒
                                break
                            i += 1

                elif case02['operation'] == '等待':
                    time.sleep(case02['time'])

                elif case02['operation'] == '判断':
                    if case02['method'] == 'xpath':
                        element = self.driver.find_element_by_xpath(case02['path'])
                        # 生成判断结果后,将结果存储在列表中
                        if element.text == case02['text']:
                            check_results.append(True)
                        else:
                            check_results.append(False)

                elif case02['operation'] == '点击':
                    element = self.driver.find_element_by_xpath(case02['path'])
                    element.click()

                elif case02['operation'] == '悬停':
                    element = self.driver.find_element_by_xpath(case02['path'])
                    ActionChains(self.driver).move_to_element(element).perform()  # 鼠标悬浮在元素的中间
                    time.sleep(3)

                elif case02['operation'] == '截屏':
                    self.screenShot(case02['text'])

                elif case02['operation'] == '跳转新页面':
                    self.driver.close()  # 关闭当前页签
                    # 切换窗口
                    n = self.driver.window_handles  # 获取当前页所有窗口句柄
                    self.driver.switch_to.window(n[0])  # 切换到第一个
                    time.sleep(3)

                elif case02['operation'] == '输入':
                    element = self.driver.find_element_by_xpath(case02['path'])
                    element.send_keys(case02['text'])

                elif case02['operation'] == '打印':
                    element = self.driver.find_element_by_xpath(case02['path'])
                    print(element.text)

                elif case02['operation'] == '清空':
                    element = self.driver.find_element_by_xpath(case02['path'])
                    element.clear()

        # 遍历判断结果列表;列表中有false,就返回false;没有false,就不返回结果
        for i in check_results:
            if i is False:
                return i

4.创建驱动文件

接下来需要:根据数据自动生成用例文件、自动将用例添加进测试套件中、自动启动运行器;由于这些操作都需要自动执行;所以需要创建一个驱动文件case_server.py

5.生成用例文件的方法

在驱动文件case_server.py中,写入生成用例文件的方法,根据数据批量生成用例文件

# 调用读取数据的方法
from com.baidu.pages.dataRead import dataRead


# 1.读取测试用例模板,每个sheet页,在test_cases文件夹下创建一个对应的TestCase文件
def createCaseFile():
    data_dict = dataRead()  # 获取测试用例模版数据字典
    print(data_dict)
    for case_name in data_dict:  # 遍历第一层字典 --- 所有的sheet都要创建TestCase文件
        print("用例名称:"+case_name)

        # 文件名称 --- 以sheet页名称命名
        file_name = '../test_cases/'+case_name+'.py'
        # 给TestCase文件写入内容 --- 初始化页面对象时会调用DataPerform方法(数据转化为selenium操作的方法)
        f = open(file_name, 'w')
        f.write("""
from com.baidu.common.myUnit import MyUnit
from com.baidu.pages.dataPerform import DataPerform
from com.baidu.pages.dataRead import dataRead


class """ + case_name + """(MyUnit):

    # 测试用例类里只需要编写 测试用例函数就可以
    def test_01_home(self):
        # 初始化页面对象
        data_perform = DataPerform(self.driver)
        # 取出数据
        # data = home.readTable('../data/数据.xlsx','数据','A1')
        # 调用逻辑函数
        data_dict = dataRead()
        case_name = '""" + case_name + """'
        case01 = data_dict[case_name]
        print(case01)
        check_results = data_perform.data_perform(case01)
        print(check_results)
        if check_results is None:
            check_results = True
        # 断言判断
        self.assertEqual(True, check_results)
""")
        f.close()

6.将用例加入测试套件的方法(用例执行文件)

在驱动文件case_server.py中,写入生成run_test_case.py文件的方法,并把TestCase文件批量添加进测试套件里

# 2.在run_test_case文件夹下创建run_test_case.py文件,测试套件中套入TestCase文件
def createRunTestCase():
    file = open('run_test_case.py', 'a')
    data_dict = dataRead()  # 获取测试用例模版数据字典
    # print(data_dict)
    for case_name in data_dict:  # 遍历第一层字典 --- 所有的TestCase文件都引入运行文件中
        # print("用例名称:" + case_name)
        file.write("""
from com.baidu.test_cases.""" + case_name + """ import """ + case_name + """
""")
    file.write("""
from com.baidu.run_test_case.HTMLTestRunnerX import HTMLTestRunner
import unittest


# 1 获取测试套件
suite = unittest.TestSuite()
# 2 测试套件中添加测试用例
""")
    data_dict = dataRead()  # 获取测试用例模版数据字典
    print(data_dict)
    for case_name in data_dict:  # 遍历第一层字典 --- 所有的TestCase都添加到测试套件中
        print("用例名称:" + case_name)
        file.write("""
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(""" + case_name + """))
""")
    file.write("""
# 3 获取运行器对象
f = open('../repots/baidu.html', mode='wb')
# stream报告存储位置 verbosity报告详细成都 title报告名称
runner = HTMLTestRunner(stream=f, verbosity=3, title='大屏首页标题测试报告')
# 4 生成测试报告
runner.run(suite)
""")
    file.close()

7.执行运行文件的方法

在驱动文件case_server.py中,写入执行运行文件run_test_case.py的方法

import os

# 3.执行run_test_case.py文件
def implementRunTest():
    os.system('python run_test_case.py')

8.恢复初始状态的方法

在驱动文件case_server.py中,写入删除/清空文件的方法;用例执行完毕后,可以删除生成的所有文件,恢复到开始的状态

import os

# 4.删除对应的TestCase文件,清空run_test_case.py文件,
def clearFile():
    data_dict = dataRead()  # 获取测试用例模版数据字典
    # print(data_dict)
    for case_name in data_dict:  # 遍历第一层字典 --- 删除所有的TestCase文件
        file_name = '../test_cases/' + case_name + '.py'
        os.remove(file_name)  # 删除对应的TestCase文件

    # 清空run_test_case.py文件
    file_run = open('./run_test_case.py', 'w')
    file_run.write("""""")

9.进行测试

在驱动文件case_server.py中,调用四个方法:生成用例文件、将用例加入测试套件、执行运行文件、恢复初始状态,进行一次完整的测试

if __name__ == '__main__':
    # 生成用例文件
    createCaseFile()
    # 将用例加入测试套件
    createRunTestCase()
    # 执行运行文件
    implementRunTest()
    # 恢复初始状态
    clearFile()

框架的维护使用

1.在Excel表格中添加用例,sheet页签包含“test_case”为一条有效的测试用例,操作步骤的填写要求,见“改造过程第一点”;

2.在驱动文件case_server.py中,执行该文件。

课程简介:课程介绍你是否在寻找机会进入自动化测试领域?你是否渴望学习selenium webdriver + Java以及**的框架和技术进行web自动化测试?你是否感兴趣学习Selenium如何用在你现有的项目里的?这门课带你从Selenium搭建环境开始讲起,然后学习常用方法,单元测试,PO设计模式, jenkins等。我们假设学员没有任何自动化经验,来设计的这套课程。每个课题都从最基础的开始讲起。Selenium相关的该覆盖的课题都覆盖了。全程手写代码,逐步迭代,方便学习。子都是来自于真实的web应用项目,帮助你理解不同的组件怎么用上自动化,这将展示给你一个行业层面的框架,增加自信心。这门课涵盖到基础到高级项目实战。您将会学到什么学完课程以后,你将了解Selenium Webdriver知识你将具备设计数据驱动框架、Page Object、等搭建自动化框架的能力用众多实对Selenium现实场景应用进行深入理解了解单元测试, Jenkins, HTML报告,并发测试 你从网上随便选择一个网站,都可以尝试实现自动化,用所有可能的测试用例进行自动化测试将提高你的编码技能,以编写最优化的自动化测试代码你基本可以应对任何Selenium面试,并能从设计阶段开始领导整个Selenium自动化项目你将能够创建漂亮的报告来打动客户或领导更深入地理解自动化指南和代码质量标准会附带一个练习网站,可以用上所有可用的WebDriver功能,实现自动化【适合人群】软件手动测试人员想转为自动化测试的人员自动化软件测试人员想加强专业技能的刚毕业学生想从事软件行业QA 组长或项目经理【课程优势】学完课程以后,你将拥有完整的Selenium Webdriver知识,完整的项目实战【讲师介绍】资质介绍:12年以上开发、自动测试方面经验,其中7年以上测试开发经验,现为技术架构师新书“Python3+Selenium3自动化测试项目实战”作者【课程咨询】作者联系QQ:2574674466 完善的学习文档            
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值