演练:Java桌面自动化测试项目

介绍

本次演练介绍了在Windows平台上如何自动化操作Java桌面应用。Java开发图形界面的GUI库有两个——Swing与AWT,目前市面上比较常见的还是前者。本次演练使用一个简单的、使用Swing开发的租车应用实例做Java自动化测试的演练。

Q: Java应用必须使用Java识别技术吗?

A: 不一定。这取决于该应用使用的GUI框架的组件属于自绘制还是对平台原生控件的封装。比如AWT就是抽象了系统原生控件,同样的Java.CheckBox,在Windows系统中可能使用的就是Windows原生的CheckBox控件,而在Mac中可能使用的就是Mac的CheckBox,因此这类应用都可以使用系统对应的技术进行识别,不需要使用Java识别技术。而Swing的控件都是自绘制的,在不同类型的系统中能保持相对统一的控件样式,但是需要使用专门的Java识别技术。CukeTest支持多种识别技术,包括原生Windows的识别技术以及Java识别技术,可以根据被测应用的实际情况选择对应的技术。

被测应用介绍

这次用于自动化的Java应用是一款租车应用,包不仅包含了完整的自动化流程,还包含各种复杂控件,比如列表、树、表格等,非常适合用于进行Java自动化测试的练手。
应用中的列表
应用中的树
应用中的表格

录制生成Java脚本

1. 项目创建

打开CukeTest客户端,创建项目,并填写项目名称,注意项目模版选择的是Win模版。项目创建完成之后,会自动打开项目首页。

创建项目

2. 开始录制脚本

在主界面点击录制设置,将被测应用的路径填进去,就可以开始录制。

录制脚本

这里我们使用上述提到的样例应用CarRental.jar,录制一个查看订单的场景:

  • 打开订单界面
  • 根据关键词搜索订单

录制时的界面如下:

录制界面

添加检查点

在自动化测试中,检查点(Checkpoint)是验证应用状态是否符合预期的关键部分。在CukeTest中,您可以在录制过程中快捷添加检查点。具体操作步骤如下:

  1. 快速打开检查点对话框:在录制时,通过按住Alt键并右击目标控件,您可以快速打开检查点对话框。这个功能让你能够在进行操作的同时,即时地添加验证步骤,提高测试脚本的编写效率。

  2. 添加属性检查点:对于本测试用例,我们将添加一个属性检查点来验证Number of Rental Cars下方的Label控件中的文本。在“属性检查点”列表中,选择“text”属性(其值应为“3”),这就是我们要验证的目标属性。

  3. 确认和插入检查点脚本:选择需要验证的属性后,点击确认按钮。相应的检查点脚本就会被插入到我们的录制脚本中。

如果需要添加图像检查点,只需切换到图像检查点标签页,并勾选需要检查的图片。这种检查点用于验证应用界面上特定图像的出现,非常适合那些以视觉元素为核心的测试场景。

添加检查点

接着可以继续操作被测应用,因为录制已经开始了的缘故,所有操作都会同步的生成自动化脚本,可以在编辑器中看到。当所有操作完成后,点击工具栏中的 “停止” 按钮,就录好了一个自动化脚本。录制生成的脚本内容如下:

JavaScript
const { RunSettings, Util } = require("leanpro.common");
const { JavaAuto } = require("leanpro.java");
(async () => {
    await RunSettings.set({slowMo: 1000, reportSteps: true});

    let modelJava = JavaAuto.loadModel("C:\\path_to_model\\model1.tmodel");

    //启动应用 "CarRental.jar"
    await Util.launchProcess("C:\\path_to_jar_file\\CarRental.jar", {"shell": true});

    //点击 "Login"
    await modelJava.getButton("Login").click();

    //点击 "View_Orders"
    await modelJava.getButton("View_Orders").click();

    //设置控件值为 "Peter"
    await modelJava.getEdit("Search").set("Peter");

    //点击 "Search1"
    await modelJava.getButton("Search1").click();

    //检查属性
    await modelJava.getEdit("Number_of_Rental_Cars").checkProperty("text", "3");

    //点击 "Home"
    await modelJava.getButton("Home").click();

})();

3. 运行录制好的脚本

点击 工具栏【只显示脚本列】切换CukeTest视图为只显示脚本栏,点击【运行脚本】:

运行脚本

可以看到回放顺利的完成了,但是回放的操作速度并不是飞快,这是因为CukeTest的录制默认打开了“慢动作”这个开关,所以在生成的脚本中加入了slowMo这个选项并设为1000,将各个操作的间隔延长到1秒,这里我们将其设为0就可以让自动化以最快的速度运行了。

生成的脚本中设置了slowMo的值:

const { RunSettings } = require("leanpro.common");  
// ……  
await RunSettings.set({slowMo: 1000, reportSteps: true});

整合自动化测试用例与代码

上面的操作仅仅只是将自动化操作部分录制下来了,也就是只能回放操作步骤,还不能算是测试,因为测试脚本中除了测试操作以外还需要有断言部分,即对测试操作的结果进行验证。

下面将录制的脚本与自动化测试结合起来。

1. 创建应用模型

录制生成的代码运行需要依赖录制时使用的模型文件,所以在整合代码之前需要先创建本次测试需要的模型文件。这里可以直接使用录制生成的模型,将它拷贝到features/step_definations目录下,并重命名为model1.tmodel

如果项目中已经存在模型文件,您可以打开这个已有模型文件和新录制的模型文件。然后,通过将新录制的模型的根节点拖拽到已有的模型树中,实现模型的复制。接下来,右击复制生成的节点,选择“合并到兄弟节点”,完成模型的合并。这样,就可以在已有模型中使用新录制时操作到的控件对象。 此外,您也可以在录制的时候选择“录制到已有模型”,这会直接将新的控件对象保存到现有模型中,进一步简化整合过程。

2. 编写用例场景

打开目录中的.feature文件,用自然语言编写与刚刚的测试对应的业务场景。这是使测试变得更加易读、更加便于管理的重要的一步: 用例场景

接下来可以切换剧本的编辑模式到 文本 模式,将以下内容复制进去,再切换回 可视 模式:

步骤2中的文本是通过右击步骤选择【添加文本字符串】来添加的,详见步骤编辑

# language: zh-CN
功能: Java自动化API测试
使用CarRental应用进行Java自动化API的测试与验证

  场景: 查看租车订单
    * 登录账户
    * 进入订单界面
    * 在搜索框输入关键词"Peter"
    * 点击Search按钮
    * Number of Rental Cars应为3
    * 返回首页

3. 编写步骤代码

打开definitions目录下的definitions.js文件,点击剧本中每个步骤后面的灰色按钮,可以在definitions.js文件中生成对应的代码样例。
步骤代码

将录制的代码按照操作步骤的顺序,分别复制到definitions.js文件中,并做对应的修改。

修改完成后如下:

JavaScript
Then("登录账户", async function () {
    //点击 "Login"
    await modelJava.getButton("Login").click();
});

Then("进入订单界面", async function () {
    //点击 "View_Orders"
    await modelJava.getButton("View_Orders").click();
});

Then("在搜索框输入关键词{string}", async function (name) {
    //设置控件值为 "Peter"
    await modelJava.getEdit("Search").set(name);
});

Then("点击Search按钮", async function () {
    //点击 "Search1"
    await modelJava.getButton("Search1").click();
});

Then("Number of Rental Cars应为{int}", async function (check_num) {
    //检查属性
    await modelJava.getEdit("Number_of_Rental_Cars").checkProperty("text", check_num);
});

Then("返回首页", async function () {
    //点击 "Home"
    await modelJava.getButton("Home").click();
});

整合后的完整脚本

结合剧本整合了录制脚本后,整个definitions.js脚本文件内容如下:

JavaScript
const { BeforeAll } = require('cucumber');
const { Given, When, Then, setDefaultTimeout } = require('cucumber');
const { JavaAuto } = require("leanpro.java");
const { Util } = require('leanpro.common');

//设置步骤超时时间为60秒
setDefaultTimeout(60 * 1000); 

// 加载Windows应用的UI模型文件
let modelJava = JavaAuto.loadModel(__dirname + "/model1.tmodel");

//// 你的步骤定义 /////
BeforeAll(async function () {
    //启动应用 "CarRental.jar"
    await Util.launchProcess("C:\\path_to_jar_file\\CarRental.jar", { "shell": true });
})

Then("登录账户", async function () {
    //点击 "Login"
    await modelJava.getButton("Login").click();
});

Then("进入订单界面", async function () {
    //点击 "View_Orders"
    await modelJava.getButton("View_Orders").click();
});

Then("在搜索框输入关键词{string}", async function (name) {
    //设置控件值为 "Peter"
    await modelJava.getEdit("Search").set(name);
});

Then("点击Search按钮", async function () {
    //点击 "Search1"
    await modelJava.getButton("Search1").click();
});

Then("Number of Rental Cars应为{int}", async function (check_num) {
    //检查属性
    await modelJava.getEdit("Number_of_Rental_Cars").checkProperty("text", check_num);
});

Then("返回首页", async function () {
    //点击 "Home"
    await modelJava.getButton("Home").click();
});

执行

点击【运行项目】,可以看到自动化执行完成后生成对应的测试报告。 测试报告

更多Java自动化能力,参见Java桌面应用自动化

results matching ""

    No results matching ""