QTest测试框架,Gui测试

简介: QTest测试框架,Gui测试

前两篇文章,小豆君主要对QTest的非Gui测试进行了介绍,既然Qt最强的是界面部分,那今天我们就来看下界面的单元测试,QTest是如何做的。


众所周知,既然使用界面,当然就需要和用户交互,比如,鼠标点击,在文本框中输入文本,既然要自动化测试,那必须将鼠标的点击事件,键盘的输入事件等进行模拟。


为此,QTest::keyClicks()模拟在该控件上输入按键序列,基本等同于输入字符串。此外,还也可以指定键盘组合按键,例如与ctrl,shift等按键的组合,并在每次单击按键后设置延迟(以毫秒为单位)。


类似的方式,还可以使用QTest::keyClick()、QTest::keyPress()、QTest::keyRelease()、QTest::mouseClick()、QTest::mouseDClick()、QTest::mouseMove()、QTest::mousePress()和QTest::mouseRelease()函数来模拟GUI事件。


下面的一个例子,我们主要介绍keyClicks的用法,其它类同。

如下图所示,在输入价格和成本后,自动显示利润。我们为该窗口类取名为CommodityWidget




1 创建CommodityWidget窗口


ui界面如上图所示。


commoditywidget.h

#ifndef COMMODITYWIDGET_H
#define COMMODITYWIDGET_H
#include <QWidget>
namespace Ui {
class CommodityWidget;
}
class CommodityWidget : public QWidget
{
    Q_OBJECT
public:
    friend class CommodityTest;
    explicit CommodityWidget(QWidget *parent = 0);
    ~CommodityWidget();
    double  costing() const;
    double  price() const;
    double  profit() const;
private slots:
    void showProfit();
    void on_line_price_textChanged(const QString &arg1);
    void on_line_costing_textChanged(const QString &arg1);
private:
    Ui::CommodityWidget *ui;
};
#endif // COMMODITYWIDGET_H


在头文件中的

friend class CommodityTest;

因为CommdityTest模拟键盘事件,需要直接访问ui界面中的控件,所以将它声明为CommodityWidget的友元类。


commoditywidget.cpp

#include "commoditywidget.h"
#include "ui_commoditywidget.h"
#include "commodity.h"
CommodityWidget::CommodityWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CommodityWidget)
{
    ui->setupUi(this);
}
CommodityWidget::~CommodityWidget()
{
    delete ui;
}
double CommodityWidget::costing() const
{
    return ui->line_costing->text().toDouble();
}
double CommodityWidget::price() const
{
    return ui->line_price->text().toDouble();
}
double CommodityWidget::profit() const
{
    return ui->line_profit->text().toDouble();
}
void CommodityWidget::showProfit()
{
    double c = costing();
    double p = price();
    Commodity commodity("beer_1", "啤酒", c, p);
    ui->line_profit->setText(QString::number(commodity.profit()));
}
void CommodityWidget::on_line_price_textChanged(const QString &arg1)
{
    showProfit();
}
void CommodityWidget::on_line_costing_textChanged(const QString &arg1)
{
    showProfit();
}



2 编写测试函数

在CommodityTest的头文件中添加如下槽函数

头文件:

private slots:
    //成本
    void case1_gui_costing();
    //价格
    void case2_gui_price();
    //利润
    void case3_gui_profit();


源文件,注意这里添加了ui头文件:

#include "commoditytest.h"
#include "commodity.h"
#include "commoditywidget.h"
#include "ui_commoditywidget.h"
void CommodityTest::case1_gui_costing()
{
    CommodityWidget w;
    //模拟按键,在键盘上输入成本 5.0
    QTest::keyClicks(w.ui->line_costing, "5.0");
    QCOMPARE(w.costing(), 5.0);
}
void CommodityTest::case2_gui_price()
{
    CommodityWidget w;
    //模拟按键,在键盘上输入价格 7.2
    QTest::keyClicks(w.ui->line_price, "7.2");
    QCOMPARE(w.price(), 7.2);
}
void CommodityTest::case3_gui_profit()
{
    CommodityWidget w;
    //模拟按键,在键盘上输入成本5.0,价格7.2 
    //最后比较利润是否为2.2
    QTest::keyClicks(w.ui->line_costing, "5.0");
    QTest::keyClicks(w.ui->line_price, "7.2");
    QCOMPARE(w.profit(), 2.2);
}


运行程序,如下图:




3 多数据测试Gui

这和上一节的多数据测试框架基本相同,只是这里换成了Gui,具体我就不讲了,不明白的可以参考上一篇文章QTest测试框架,多数据测试


下面直接上代码

头文件:

private slots:
    //利润
    void case3_gui_profit();
    void case3_gui_profit_data();


源文件:

void CommodityTest::case3_gui_profit()
{
    QFETCH(QTestEventList, costing);
    QFETCH(QTestEventList, price);
    QFETCH(double, expected);
    CommodityWidget w;
    costing.simulate(w.ui->line_costing);
    price.simulate(w.ui->line_price);
    QCOMPARE(w.profit(), expected);
}
void CommodityTest::case3_gui_profit_data()
{
    QTest::addColumn<QTestEventList>("costing");
    QTest::addColumn<QTestEventList>("price");
    QTest::addColumn<double>("expected");
    QTestEventList costing1;
    QTestEventList price1;
    costing1.addKeyClicks("5.0");
    price1.addKeyClicks("7.2");
    QTest::newRow("normal") << costing1 << price1 << 2.2;
    QTestEventList costing2;
    QTestEventList price2;
    costing2.addKeyClicks("5.0");
    price2.addKeyClicks("3.2");
    QTest::newRow("negative") << costing2 << price2 << -1.8;
}


运行如下:



现在假设CommdityWidget中的profit函数有bug,例如,我将toDouble改成了toInt,我们来看看会出现什么结果:

double CommodityWidget::profit() const
{
    return ui->line_profit->text().toInt();
}





看,测试程序告诉我们在文件commoditytest.cpp的第88行出现问题,并且,正确的结果应该是2.2,而实际返回的结果是0,我们查看第88行,原来是profit函数有bug,再查看该函数的实现,原来是将toDouble写成了toInt,所以导致输出结果为0




前一阵,在群中我看到有一位朋友提出,由于项目需求,需要人不停的点击鼠标按键来获取某些数据,而今天介绍的Gui测试框架是完全可以实现的,并且只需要四五行代码就能完全胜任。


关于测试框架的内容大概就这么多了,但里面还有很多有意思的函数,如果有朋友感兴趣,可以直接查看Qt帮助文档就可以啦。


最后,小豆君再啰嗦几句,对于测试代码可能有很多人懒得去写,但是,一旦写好了测试程序,你的开发工作会变得相当轻松,每次修改或重构程序后,直接运行测试程序,它会很快的帮助你定位问题,而不是每次写完程序后,还要重复的去自己输入测试数据,在界面上各种点击。


测试代码,是真正做到了一键运行,检查工作全部交给电脑,而你也可以喝喝茶,休息休息啦。


更多分享请关注微信公众号:小豆君Qt分享,只要关注,便可加入C++\Qt交流群,一起学习,更可获得所有文章源码。

相关文章
|
5天前
|
设计模式 安全 测试技术
深入理解与应用自动化测试框架 — 以Selenium为例网络防线的构筑者:洞悉网络安全与信息安全的核心要素
【5月更文挑战第29天】 在快速迭代的软件开发过程中,自动化测试已成为提高测试效率、确保软件质量的重要手段。本文将深入探讨自动化测试框架Selenium的核心概念、架构以及实际应用中的关键技巧,旨在为读者提供一篇系统性的分析与实践指南。文章首先概述了自动化测试的必要性和Selenium框架的基本特征;随后详细剖析了Selenium的组件结构,并结合实例讲解如何高效地设计和执行测试用例;最后,讨论了当前自动化测试面临的挑战及未来发展趋势。
|
3天前
|
敏捷开发 Java 测试技术
深入理解自动化测试框架Selenium的设计理念与最佳实践
【5月更文挑战第31天】 在现代软件开发过程中,自动化测试是确保产品质量和加快交付速度的关键因素。Selenium作为一种广泛使用的自动化测试框架,它支持多种浏览器、操作系统和编程语言,极大地方便了测试人员编写和维护测试用例。本文将探讨Selenium的核心设计理念,包括其架构、组件和工作流程,并分享如何在实际项目中应用Selenium的最佳实践,以提高测试效率和准确性。通过分析真实案例,我们将展示Selenium如何帮助企业实现持续集成和持续部署(CI/CD)的目标,同时保证软件的稳定性和可靠性。
|
3天前
|
设计模式 敏捷开发 监控
深入理解自动化测试框架的设计原则与实践
【5月更文挑战第31天】 在软件开发的复杂多变环境中,自动化测试已成为确保产品质量和加快交付速度的关键因素。本文将探讨自动化测试框架的设计原则,并结合实际案例分析如何构建一个高效、可扩展且易于维护的自动化测试框架。我们将透过不同的测试场景,从模块化、抽象化到数据驱动等设计模式,剖析框架构建的最佳实践。通过阅读本文,读者能够获得构建强大自动化测试框架的深刻见解,并应用于实际工作中,以提升软件测试效率和准确性。
4 0
|
4天前
|
机器学习/深度学习 敏捷开发 人工智能
深入理解软件测试中的自动化框架选择
【5月更文挑战第30天】 在快速迭代的软件开发过程中,高效的测试策略是确保产品质量的关键。本文将探讨自动化测试框架的选择对软件测试效率和质量的影响。通过分析不同类型项目的需求与特点,我们讨论如何根据团队的技术栈、项目周期和资源情况来选取合适的自动化测试框架。文章还将涉及持续集成环境下自动化测试框架的最佳实践,以及新兴测试技术对现有框架选择的潜在影响。
|
4天前
|
IDE Java 测试技术
Java中JUnit等测试框架的使用
Java中JUnit等测试框架的使用
|
4天前
|
敏捷开发 自然语言处理 JavaScript
探索自动化测试框架的选择标准与实践应用
【5月更文挑战第30天】 在软件开发的复杂多变环境中,自动化测试已成为确保产品质量和加快上市速度的关键。本文深入探讨了选择自动化测试框架时需考虑的标准,并通过具体案例分析如何在项目中成功实施。我们将覆盖框架选择过程中的性能、可靠性、易用性及可维护性四个核心要素,并结合业界最佳实践,提出一套实用的框架评估与应用流程。
|
4天前
|
Dart 前端开发 测试技术
移动应用开发的未来:跨平台框架与原生系统的融合深入理解软件测试中的持续集成与持续部署(CI/CD)
【5月更文挑战第30天】 在本文中,我们将深入探讨移动应用开发领域的最新趋势:跨平台开发框架与原生操作系统的融合。随着移动设备成为日常生活的核心,高效、灵活且性能卓越的应用程序需求日益增长。文章分析了当前主流的跨平台工具如React Native和Flutter,并探讨了它们如何与iOS和Android等原生系统相互作用,以及这种融合对开发者、用户和整个移动生态系统意味着什么。我们还将预测未来可能的技术发展,并提出相应的策略建议。
|
4天前
|
敏捷开发 监控 测试技术
深入探索自动化测试框架的选择与构建
【5月更文挑战第30天】在追求高效、可靠的软件发布周期中,自动化测试成为确保产品质量的关键。本文将探讨如何选择合适的自动化测试框架并指导构建一个符合项目需求的框架体系。我们将通过分析不同测试场景和需求,评估Selenium、Appium和JUnit等流行工具的优缺点,并提供策略性建议,以助读者构建出既灵活又稳定的自动化测试环境。
13 3
|
4天前
|
前端开发 测试技术 API
深入理解自动化测试框架Selenium的设计与实现
【5月更文挑战第30天】 本文将深入探讨和分析自动化测试框架Selenium的设计理念、架构以及其在实际开发中的应用。Selenium作为一款广泛使用的开源自动化测试工具,它的灵活性和高效性使其成为Web应用测试的首选工具。文章将从Selenium的核心组件出发,详细解析其工作原理,并结合实际案例讨论如何优化测试脚本,提高测试效率。此外,还将介绍Selenium Grid的使用,展示如何通过分布式测试加速测试过程。最后,文章将展望Selenium在未来技术演进中可能面临的挑战和发展方向。
|
4天前
|
设计模式 敏捷开发 监控
深入探索自动化测试框架的选择与构建
【5月更文挑战第30天】软件测试是确保产品质量的关键环节,随着敏捷开发的流行及持续集成的普及,自动化测试成为提升效率、保障质量的重要手段。本文将探讨如何根据项目需求选择适合的自动化测试框架,并提供一个构建高效自动化测试框架的策略。文中不仅分析了当前流行的自动化测试工具,还提出了一套结合最佳实践的构建流程,旨在帮助团队打造可靠且易于维护的自动化测试环境。