Selenium 报表自动化测试——黑盒测试篇

news2025/3/6 22:14:10

目录

前言:

背景

需求

分析

解决思路

解决方案

测试流程图

实现的功能

用例代码

两种测试方式

随机测试

指定测试

总结


前言:

Selenium是一个广泛使用的自动化测试工具,用于Web应用程序的测试。它提供了一组功能强大的API,可以模拟用户在浏览器中的操作,如点击、输入、选择等。通过使用Selenium,测试人员可以自动执行各种测试用例,以验证Web应用程序的功能和用户体验。

在黑盒测试中,测试人员只关注应用程序的输入和输出,而不考虑内部的实现细节。这种测试方法可以模拟真实用户的行为,从而更全面地评估应用程序的功能和性能。

报表是许多Web应用程序中常见的功能之一,它用于展示和分析数据。在报表自动化测试中,测试人员使用Selenium来模拟用户在应用程序中生成和查看报表的操作。通过自动化测试,可以确保报表的正确性、可靠性和可用性。

背景

公司的 ERP 系统有很多报表页面,每个月都会有一两个报表的功能进行修改,页面查询条件很多,
功能测试的同事尽可能的穷举出各种参数组合去查询,但由于参数组合的数量太大,人工测试的用例只能算九牛一毛,
依然有大部分漏测的场景可能发现问题,上线之后被用户投诉。

基于这个背景,引入自动化测试,旨在通过程序穷举出各种查询场景自动进行测试,并记录各场景的测试结果。

需求

从背景中收集到以下需求:

  1. 页面上有很多查询条件
  2. 穷举查询条件的组合
  3. 记录各组合的测试结果

分析

先看看页面长什么样子。

由此页面我们可以得出参数的大致列表:

<aa></aa>
<bb></bb>
<cc></cc>
<dd></dd>
<ee></ee>
……

我们把这些参数进行组合,(此处省略 N 字。。。组合公式自行去查阅资料)可以得到以下数量
组合数量 = 2的参数个数次幂-1
假设页面有 3 个参数 aa,bb,cc,那么组合出来的参数为:{[aa], [bb], [cc], [aa,bb], [aa,cc], [bb,cc], [aa,bb,cc]}
如果页面有 10 个参数,则这些参数组合的数量为:2 的 10 次方-1 = 1023

但上面求出来的数量仅仅只是参数的值为固定数量的组合个数,但实际上某个参数的取值可能是以下情况:

<aa>value1,value2,value3</aa>
or
<aa>value1</aa>
or
<aa>value1,value2</aa>
or
……
我们可以得知

页面条件组合出来的数量无穷大!!!😤😤😤

解决思路

从实际场景出发,了解业务初衷

我们从上面的分析可以得出一个结论,这是一个看似无法完成的任务。怎么把一个理论上来说不可能完成
的任务,变成一个可行的解决方案,就需要我们对实际的业务进行分析了。

先说自动化面临的问题:

  1. 自动化用例量庞大。假设页面有 10 个参数,每个参数固定一个值,则有 1023 个组合
  2. 自动化用例耗时长。一个完整的页面输入参数点击查询的用例大概需要 5~10 秒的时间,再乘以以千为单位的用例个数。。。 不说其他,单这两项就够秒杀该功能不适合做自动化的。 怎么办呢?竟然正常的路走不通,那我们就想点非常规的路子。

咱们不妨抛开业务,想想什么自动化用例才是好用例:

  1. 脚本通用,一份脚本支持所有用例执行。😍
  2. 脚本执行时间短,最好分分钟跑完。☺
  3. 覆盖更多测试场景,这个当然是越多越好。👏

回到正题,竟然这个业务本身就非常特殊,我们就没有必要去遵循自动化用例的设计原则了,直接按照我们心目中的完美用例去实现。

  1. 脚本通用。我们可以写一份脚本,然后通过循环读取参数去页面查询。
  2. 执行时间。如此庞大的用例量自然无法通过人工来写的,我们就想办法通过程序去自动生成用例。
  3. 覆盖度高。从业务角度来设置查询场景,如:参数全设置查询,参数不设置查询,等各种场景。

解决方案

最终我们得出一个比较满意的测试解决方案:

  • 使用数据驱动模式,维护参数配置文件,一份代码,所有用例都可执行
  • 测试用例通过参数组合生成,提供开关控制用例生成数量
  • 指定场景测试 + 随机测试(从参数组合中抓取随机数量的组合)

测试流程图

实现的功能

  • 代码与业务分离。不再需要写大量场景的自动化用例代码,仅需维护参数配置文件
  • 测试用例根据配置文件中的参数随机生成测试场景,场景数量可控(配置文件提供指定数量)
  • 2 层随机机制(查询条件随机组合,查询条件中具体条件中的值随机组合),保证了场景的覆盖度
  • 2 种测试方式(随机场景测试,指定场景测试)
  • 明确的测试结果。只关注点击查询后的页面结果,忽略自动化操作页面元素失败干扰测试结果(用例在页面操作失败依然往下执行)

用例代码

public class RandomParamatersQueryTest {
    private WebDriver webDriver = null;
    private SoftAssert softAssert = new SoftAssert();
    WebManager webManager = null;
    WebElementCheck webCheck = null;

    @Test
    public void randomParamatersQueryTest() {
        String parameterXmlPath = ConfigReader.getInstance().getValue("parameterXmlPath");
        String randomCaseXmlPath = ConfigReader.getInstance().getValue("randomCaseXmlPath");
        String randomexcelPath = ConfigReader.getInstance().getValue("randomexcelPath");

        // 使用Firefox浏览器
        webDriver = WebDriverManager.GetDriver(BroswerType.FIREFOX);

        webManager = new WebManager(webDriver, softAssert);
        webCheck = new WebElementCheck(webDriver, softAssert);

        PublicMethod common = new PublicMethod(webManager, webCheck);
        SalesReport sReport = new SalesReport(webManager);

        // 登录、跳转到指定报表页
        common.login(ConfigReader.getInstance().getValue("loginURL"), ConfigReader.getInstance().getValue("loginEmail"),
                ConfigReader.getInstance().getValue("loginPassword"));
        sReport.navigateToSalesReport();
        sReport.switchToFrame();

        // 参数生成参数配置文件
        ReportProvider.saveParamatersToCaseXML(parameterXmlPath, randomCaseXmlPath);
        webManager.threadWait(3);
        // 读取参数配置文件,做UI自动化测试
        XmlReader xmlReader = XmlReader.getInstance(randomCaseXmlPath);

        // 创建测试报告Excel
        String reportName = "sales report";
        ExcelOperate.getInstance().createExcel(reportName, randomexcelPath);

        List<String> configIds = xmlReader.getAttributeValue("id");
        for (String configId : configIds) {
            try {
                // 设置查询参数
                sReport.setQueryParas(randomCaseXmlPath, configId);
                sReport.clickSearch();

                try {
                    // 判断错误提示框是否出现,如果出现,判定该用例执行失败
                    webManager.dynamicWaitAppearAndThrowException(WebElementType.XPATH,
                            "//div[@class='ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable ui-resizable']",
                            2);
                    webManager.threadWait(1);
                    String message = webCheck.getProperty(WebElementType.XPATH, "//div[@id='alert_dialog']",
                            CheckPropertyType.INNERTEXT);
                    ExcelOperate.getInstance().excelWrite2003(randomexcelPath, ExcelUpdateMode.ADD, reportName,
                            configId, "fail", message);
                } catch (Exception e) {
                    // 错误框未出现,判定用例执行成功
                    ExcelOperate.getInstance().excelWrite2003(randomexcelPath, ExcelUpdateMode.ADD, reportName,
                            configId, "success", "");
                } finally {
                    webManager.refreshBroswer();
                    sReport.navigateToSalesReport();
                    sReport.switchToFrame();
                }

            } catch (Exception e) {
                // 任何错误都不抛出,保证用例的循环执行
            }
        }

        common.logout();
    }
}

两种测试方式

随机测试与指定测试的区别在于用例配置文件一个是根据参数随机生成,一个是用户自己指定场景的参数

随机测试

参数文件

<?xml version="1.0" encoding="UTF-8"?>
<Testcases xmlns="testcase">
    <parameters>
        <grouptype>1,2,3</grouptype>
        <market>504</market>
        <ps>2877</ps>
        <orggroupby>1,2,3,4,5</orggroupby>
        <channel>287</channel>
        <channelcountry></channelcountry>
        <productline></productline>
        <pm></pm>
        <cm>2877</cm>
        <salesdate>2017-02-01,2017-02-02</salesdate>
        <country>US,UK,FR</country>
        <curno>USD</curno>
        <shippingperiod>1</shippingperiod>
        <model>TT-BH07</model>
        <sku>53-10007-001</sku>
    </parameters>
</Testcases>

生成的随机测试参数配置文件每次都会改变,这样保证了用例的场景覆盖度(生成的 case 数量可控,在配置文件中设置即可)

<?xml version="1.0" encoding="UTF-8"?>
<Testcases xmlns="testcase">
    <Testcase xmlns="" id="case1">
        <country>US,UK,FR</country>
        <channel>287</channel>
        <curno>USD</curno>
        <shippingperiod>1</shippingperiod>
        <grouptype>1,2,3</grouptype>
        <salesdatefrom>2017-02-01</salesdatefrom>
        <salesdateto>2017-02-02</salesdateto>
        <sku>53-10007-001</sku>
    </Testcase>
    <Testcase xmlns="" id="case2">
        <cm>2877</cm>
        <shippingperiod>1</shippingperiod>
    </Testcase>
    <Testcase xmlns="" id="case3">
        <country>US,UK,FR</country>
        <ps>2877</ps>
        <cm>2877</cm>
        <curno>USD</curno>
        <market>504</market>
        <orggroupby>1,2,3,4,5</orggroupby>
        <salesdatefrom>2017-02-01</salesdatefrom>
        <salesdateto>2017-02-02</salesdateto>
        <sku>53-10007-001</sku>
    </Testcase>
    <Testcase xmlns="" id="case4">
        <country>US,UK,FR</country>
        <channel>287</channel>
        <cm>2877</cm>
        <market>504</market>
        <grouptype>1,2,3</grouptype>
        <orggroupby>1,2,3,4,5</orggroupby>
        <salesdatefrom>2017-02-01</salesdatefrom>
        <salesdateto>2017-02-02</salesdateto>
        <sku>53-10007-001</sku>
    </Testcase>
    <Testcase xmlns="" id="case5">
        <shippingperiod>1</shippingperiod>
        <market>504</market>
        <orggroupby>1,2,3,4,5</orggroupby>
        <model>TT-BH07</model>
        <sku>53-10007-001</sku>
    </Testcase>
    <Testcase xmlns="" id="case6">
        <country>US,UK,FR</country>
        <channel>287</channel>
        <curno>USD</curno>
        <shippingperiod>1</shippingperiod>
        <model>TT-BH07</model>
    </Testcase>
    <Testcase xmlns="" id="case7">
        <country>US,UK,FR</country>
        <ps>2877</ps>
        <channel>287</channel>
        <curno>USD</curno>
        <market>504</market>
        <orggroupby>1,2,3,4,5</orggroupby>
        <model>TT-BH07</model>
        <sku>53-10007-001</sku>
    </Testcase>
    <Testcase xmlns="" id="case8">
        <cm>2877</cm>
        <curno>USD</curno>
        <market>504</market>
        <grouptype>1,2,3</grouptype>
        <salesdatefrom>2017-02-01</salesdatefrom>
        <salesdateto>2017-02-02</salesdateto>
        <sku>53-10007-001</sku>
    </Testcase>
    <Testcase xmlns="" id="case9">
        <country>US,UK,FR</country>
        <ps>2877</ps>
        <curno>USD</curno>
        <shippingperiod>1</shippingperiod>
        <market>504</market>
        <grouptype>1,2,3</grouptype>
        <model>TT-BH07</model>
        <sku>53-10007-001</sku>
    </Testcase>
    <Testcase xmlns="" id="case10">
        <ps>2877</ps>
        <curno>USD</curno>
        <market>504</market>
        <model>TT-BH07</model>
    </Testcase>
</Testcases>
指定测试

参数文件

<?xml version="1.0" encoding="UTF-8"?>
<Testcases xmlns="testcase">
    <Testcase id="allparamaters">
        <grouptype>1,2,3,4,5,6,7,8,9,53,54,55</grouptype>
        <market>504</market>
        <ps>3817,3782,2877,1620,3619,3661</ps>
        <orglist>1,2,3,4,5</orglist>
        <channel>12</channel>
        <channelcountry></channelcountry>
        <productline></productline>
        <pm>3660,3619,1620,2887,3813</pm>
        <cm>3661,2877,3782,1620,3817</cm>
        <salesdatefrom>2017-02-01</salesdatefrom>
        <salesdateto>2017-02-02</salesdateto>
        <country>CA,CN,DE,ES,FR,HK,IT,JP,UK,US</country>
        <curno></curno>
        <shippingperiod></shippingperiod>
        <model></model>
        <sku></sku>
    </Testcase>
    <Testcase id="noneparamaters">
        <grouptype></grouptype>
        <market></market>
        <ps></ps>
        <orglist></orglist>
        <channel></channel>
        <channelcountry></channelcountry>
        <productline></productline>
        <pm></pm>
        <cm></cm>
        <salesdatefrom></salesdatefrom>
        <salesdateto></salesdateto>
        <country></country>
        <curno></curno>
        <shippingperiod></shippingperiod>
        <model></model>
        <sku></sku>
    </Testcase>
</Testcases>

总结

通过指定测试场景与随机测试场景,达到报表黑盒自动化测试的目的。

  作为一位过来人也是希望大家少走一些弯路

在这里我给大家分享一些自动化测试前进之路的必须品,希望能对你带来帮助。

(软件测试相关资料,自动化测试相关资料,技术问题答疑等等)

相信能使你更好的进步!

点击下方小卡片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/762487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【CCF推荐】1区TOP刊,稳定检索29年,仅17天见刊,7月26即将截稿~

本期小编给大家推荐的是一本1区计算机科学类SCI. 该期刊为CCF推荐TOP刊&#xff0c;是计算机科学领域高质量期刊&#xff0c;隶属于世界前三出版社旗下。 发表与数字孪生、物联网、服务计算、智能计算、大数据、云计算、网络服务等方向相关或结合研究的高质量原创文章。 在…

关于SpringMVC的面试题

一、SpringMVC执行流程知道吗&#xff1f; 前后端分离开发环境下&#xff08;接口开发、异步请求&#xff09;&#xff1a; ①用户端发送请求到前端控制器DispatcherServlet ②DispatcherServlet收到请求调用HandlerMapping ③HandlerMapping找到具体的处理器&#xff0c;生…

itheima苍穹外卖项目学习笔记--Day8: 用户下单 / 微信支付

Day8&#xff1a;用户下单、微信支付 Day8&#xff1a;用户下单、微信支付a. 用户下单b. 微信支付 Day8&#xff1a;用户下单、微信支付 a. 用户下单 创建OrderController并提供用户下单方法&#xff1a; /*** 用户下单* param ordersSubmitDTO* return*/ PostMapping("…

数字信号转模拟信号PWM脉宽调制信号输入隔离变送器1Hz~10KHz转0-5V/0-10V4-20mA

主要特性: >>精度等级&#xff1a;0.1级。产品出厂前已检验校正&#xff0c;用户可以直接使用 >>辅助电源&#xff1a;8-32V 宽范围供电 >>PWM脉宽调制信号输入: 1Hz~10KHz >>输出标准信号&#xff1a;0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA等&…

基于ClickHouse解决活动海量数据问题 | 京东云技术团队

1、背景 魔笛活动平台要记录每个活动的用户行为数据&#xff0c;帮助客服、运营、产品、研发等快速处理客诉、解决线上问题并进行相关数据分析和报警。可以预见到需要存储和分析海量数据&#xff0c;预估至少几十亿甚至上百亿的数据量&#xff0c;所以需要选择一款能存储海量数…

Linux 6.5 内核提供对 USB4 v2 的初步支持

导读最新内核补丁显示&#xff0c;英特尔正在为 Linux 6.5 内核提供对 USB4 v2 的初步支持&#xff0c;并在其新的英特尔 Barlow Ridge 离散控制器上进行初步启用。 去年&#xff0c;USB4 v2.0 规范作为 USB4 标准的下一代版本发布。 USB4 v2 可通过 USB Type-C 线支持 80 Gbp…

配电室智能运维功能性如何?

很多物业单位在配电室运维上&#xff0c;现状普遍是人少、事多、责任大。有时电工需要同时负责多个高低压配电室值班和设备维修&#xff0c;现有人员平时忙于应付各种设备设施的报修处理&#xff0c;配电室巡检和维护工作常常流于形式。另外&#xff0c;电力运行维护专业性很强…

SAP BOM中的技术类型简介

本文介绍一下BOM中技术类型 1、简单BOM 2、派生BOM 3、多重BOM 由于BOM的技术类型系统会自动设置所以大家基本感觉不到它的存在。基本上很少有同学会关注这个地方。 我们先从简单BOM开始&#xff0c;基本每个项目实施都会用到&#xff0c;就是一个物料具有多个组件清单 这种情…

【软件测试】Git 详细实战-打标签,一篇通关...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Git 打标签 一般会…

【正点原子STM32连载】 第六十章 USB读卡器实验摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第六…

Qt开发关于3288,3128,3399程序升级方法

一、自动更新程序流程 加载本地配置文件获取获取保存的版本号 每次启动程序&#xff0c;首先从服务器请求最新的版本信息文件&#xff08;包括版本号&#xff0c;压缩包下载地址&#xff0c;更新时间&#xff0c;更新说明&#xff09; 解压下载的文件获取服务器版本号&#xff…

【状态估计】基于UKF法、AUKF法的电力系统三相状态估计研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

比较MQX、FreeRTOS和ucOS的优缺点

MQX, FreeRTOS和ucOS&#xff08;也称为μC/OS&#xff09;都是嵌入式实时操作系统&#xff08;RTOS&#xff09;中的代表性选择&#xff0c;它们各自有各自的优点和缺点。以下是它们的一些特点&#xff1a; 我这里刚好有嵌入式、单片机、plc的资料需要可以私我或在评论区扣个…

避免IDEA新建项目自动纳入git管理

引言 今天遇到了个很头疼的问题&#xff1a;我在 gitee 上创建了新的远程仓库 test1&#xff0c;然后通过 IDEA 拉取到了本地。随后我打算在该目录下新建新的 module&#xff0c;用来做不同的事情。比如这里的 mybatis 我打算用于测试 mybatis 相关的一些类、方法等。但问题是…

前端学习笔记:JavaScript基础语法(ECMAScript)

此博客参考b站&#xff1a;【黑马程序员前端JavaScript入门到精通全套视频教程&#xff0c;javascript核心进阶ES6语法、API、js高级等基础知识和实战教程】https://www.bilibili.com/video/BV1Y84y1L7Nn?p76&vd_source06e5549bf018e111f4275c259292d0da 这份笔记适用于已…

TS高级开发技巧15条

TS高级开发技巧15条 1.可选链 Optional Chaining (?.): 在不用担心遇到 null 或 undefined 值的前提下&#xff0c;可选链允许你安全访问 nested 对象属性和方法。 他会简单计算类型为 null 或者 undefined 的中间属性。 const user {name: John,address: {city: New York,p…

【C++】STL | 模拟实现简易string

目录 1. 框架搭建 2. 迭代器的实现 3. string的拷贝构造和赋值&#xff08;深拷贝&#xff09; 拷贝构造 赋值构造 4. string的增删查改 reserve 接口 resize 接口 push_back 接口 append 接口 operator() 实现 insert 接口 erase 接口 find 接口 substr 接口 cle…

若依前端使用图标

图标 前后端分离的若依前端使用的图标分为两种&#xff1a;分别是svg图标和element的图标 svg图标 1&#xff0c;使用方法 <!-- icon-class 为 icon 的名字; class-name 为 icon 自定义 class--> <svg-icon icon-class"password" class-namecustom-cla…

C++ for Reverse Words in a String

这道题是Leetcode上的151.反转字符串中的单词这道题&#xff0c;这道题给出的题目要求是&#xff1a; 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒…

Pycharm--Low Memory

Low Memory The IDE is running low on memory and this might affect performance. Please consider increasing available heap. 卡成翔 -- 已经配置成4096了啊