DevExpress WinForms中文教程 - 如何通过UI测试自动化增强应用可靠性?(二)

DevExpress WinForm拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!

UI自动化测试利用特定的工具/框架来模拟用户与界面的交互,并帮助确保应用程序满足相关的最终用户需求。当与其他测试方法(API测试、单元测试等)结合使用时,UI自动化可以提高应用程序的稳定性,减少花在手工测试上的时间,当然还可以提高用户满意度。在本文中,我们将向您展示如何使用UI自动化在Visual Studio 2022中编写简单/高级UI测试。

DevExpress WinForms中文教程图集

在开始之前,我们先看看UI测试的优势:

  • UI测试以应用程序为目标,允许您测试应用程序流(端到端测试),涵盖应用程序的所有元素,包括UI和业务逻辑(而单元测试侧重于测试应用程序中的单个模块、类或组件)。
  • UI测试有助于识别与导航、数据输入和跨不同屏幕的工作流相关的问题,这些问题可能不会被其他测试捕获。
  • UI测试为测试复杂场景和边缘情况提供了效率和可伸缩性(单元测试对于测试单个代码单元是必不可少的)。请注意,UI测试可能需要更长的时间来执行,因为它们与UI交互,并在应用程序开发管道中稍后运行(单元测试通常更快,并且在提交到存储库之前进行了检查)。

获取DevExpress v23.2.5正式版下载(Q技术交流:909157416)

在上文中(点击这里回顾>>),我们为大家介绍了UI测试自动化是如何工作的、开始创建UI自动化测试等,本文将继续介绍如何创还能UI自动化测试。

创建UI自动化测试
3. 为登录表单创建测试

在进行测试之前,我想澄清几点:

  • AutomationElement.RootElement静态属性包含根元素,使用此属性访问应用程序。
  • AutomationElement.FindFirst方法允许您找到一个特定的UI元素:
AutomationElement logInFormElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "CRM Log In Form"));

FindFirst方法有两个参数,第一个参数(scope)指定搜索的范围,第二个参数(条件)指定要匹配的标准(在我的例子中,这是一个AutomationName = "CRM Log In Form"的表单)。

UI控件可以根据其他设置(例如,Text)自动“计算”AutomationName。
如果需要,您可以显式地设置AutomationName属性或处理DXAccessible.QueryAccessibleInfo事件,来向DevExpress UI元素提供可访问性信息。

  • 在某些情况下,被测试的应用程序可能没有时间生成UI元素,因为UI自动化框架执行操作非常快。因此,我们建议使用“poll”间隔。
    下面的例子实现了FindFirstWithTimeout方法,并反复调用FindFirst(带有延迟),直到找到指定的UI元素:
public static class AutomationElementExtensions {
public static AutomationElement FindFirstWithTimeout(this AutomationElement @this,
TreeScope scope, Condition condition, int timeoutMilliseconds = 1000) {
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
do {
var result = @this.FindFirst(scope, condition);
if (result != null)
return result;
Thread.Sleep(100);
}
while (stopwatch.ElapsedMilliseconds < timeoutMilliseconds);
return null;
}
}

下面的测试将执行以下操作:

  • 输入错误的登录名和密码。
  • 确保在“LogIn”表单中显示错误消息。
[Test]
public void NonExistingUsernameLoginTest() {
afterLogInAction = CheckErrorLabel;
LogIn("TestNonExistingUser", "123456");
}
void CheckErrorLabel() {
AutomationElement errorLabelElement = loginForm.FindFirstByNameWithTimeout(
TreeScope.Children,
"Invalid User or Password",
10000);
Assert.IsNotNull(errorLabelElement);
}
void LogIn(string username, string password) {
// Finds the LogIn form and its main UI elements.
loginForm = AutomationElement.RootElement.FindFirstByNameWithTimeout(
TreeScope.Children,
logInFormAccessbleName,
10000);
AutomationElement usernameElement = loginForm.FindFirstByNameWithTimeout(TreeScope.Children, usernameAccessbleName, 10000);
AutomationElement passwordElement = loginForm.FindFirstByNameWithTimeout(TreeScope.Children, passwordAccessbleName, 10000);
AutomationElement logInButtonElement = loginForm.FindFirstByNameWithTimeout(TreeScope.Children, logInButtonAccessbleName, 10000);

// Gets automation patterns to fill "UserName" and "Password" inputs (editors).
ValuePattern usernameValuePattern = (ValuePattern)usernameElement.GetCurrentPattern(ValuePattern.Pattern);
ValuePattern passwordValuePattern = (ValuePattern)passwordElement.GetCurrentPattern(ValuePattern.Pattern);
InvokePattern invokePattern = (InvokePattern)logInButtonElement.GetCurrentPattern(InvokePattern.Pattern);

// Sets editor values. Fills in username and password input fields.
usernameValuePattern.SetValue(username);
passwordValuePattern.SetValue(password);
invokePattern.Invoke();

// Performs an action after a log in attempt.
afterLogInAction?.Invoke();
}

正如您所看到的,编写测试可以归结为获取一个AutomationElement并调用它的模式方法。

4. 为客户表单创建一个测试

让我们考虑一个更复杂的情况,并在DevExpress WinForm数据网格(GridControl)中测试数据编辑。DevExpress数据网格包含一个带有布尔值的“Is Modified”未绑定列,该列的值表示用户是否修改了“Name”列的值。

我使用TablePattern与网格控件一起工作,下面的例子展示了如何编写一个测试来修改我们的WinForms Grid中的客户名称,并检查“Is Modified”列中的值是否从false变为true:

[Test]
public void ModifiedCustomerTest() {
LogIn(testExistingUserLogin, testExistingUserPassword);

// Finds the GridControl and gets its TablePattern.
customersForm = AutomationElement.RootElement.FindFirstByNameWithTimeout(
TreeScope.Children,
customersFormAccessbleName,
10000);
AutomationElement customersGrid = customersForm.FindFirstByIdWithTimeout(
TreeScope.Children,
customersGridAutomationID,
10000);
TablePattern customersTablePattern = (TablePattern)customersGrid.GetCurrentPattern(TablePattern.Pattern);

// Activates a cell within the GridControl.
AutomationElement cellToUpdate = customersTablePattern.GetItem(1, 1);
InvokePattern testCellInvokePattern = (InvokePattern)cellToUpdate.GetCurrentPattern(InvokePattern.Pattern);
testCellInvokePattern.Invoke();

// Modifies the cell's value.
AutomationElement editingControl = customersGrid.FindFirstByNameWithTimeout(TreeScope.Descendants, "Editing control", 1000);
ValuePattern editedCellValuePattern = (ValuePattern)editingControl.GetCurrentPattern(ValuePattern.Pattern);
editedCellValuePattern.SetValue("Value updated!");
Thread.Sleep(1000); // Sets a delay for demonstration purposes.

// Selects the next data row.
AutomationElement nextRowCell = customersTablePattern.GetItem(2, 1);
SelectionItemPattern selectionItemPattern = (SelectionItemPattern)TreeWalker.ControlViewWalker.GetParent(nextRowCell).GetCurrentPattern(SelectionItemPattern.Pattern);
selectionItemPattern.Select();
Thread.Sleep(1000);

// Checks if the value in the "Is Modified" column has changed.
int isModiedColumnIndex = customersTablePattern.Current.GetColumnHeaders().ToList().FindIndex(h => h.Current.Name == "Is Modified");
AutomationElement isModifiedCell = customersTablePattern.GetItem(1, isModiedColumnIndex);
ValuePattern isModifiedCellValuePattern = (ValuePattern)isModifiedCell.GetCurrentPattern(ValuePattern.Pattern);
Assert.AreEqual(isModifiedCellValuePattern.Current.Value, "Checked");
}
5. 运行测试

要运行我刚刚创建的测试,将用tests展开项目(“TestRunner”),右键单击*.cs文件来调用上下文菜单,然后单击"Run Tests"。

DevExpress WinForms中文教程图集

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字工厂管理系统与MES系统有什么区别

随着工业4.0时代的到来&#xff0c;数字化转型已经成为制造企业发展的必然趋势。在这个过程中&#xff0c;数字工厂管理系统和MES管理系统都扮演者至关重要的角色。然而&#xff0c;尽管两者都致力于优化生产流程和提高生产效率&#xff0c;但它们在实际应用、功能定位和系统架…

Datapump数据迁移方案

环境准备 确认源数据库和目标数据库的版本 确保源数据库和目标数据库的Oracle版本兼容&#xff0c;以保证Datapump工具能够正常工作。 硬件资源检查 确认源数据库和目标数据库服务器的硬件资源&#xff08;如CPU、内存、存储空间&#xff09;能够满足数据迁移的需求。 网络连…

基于STM32的智能垃圾分类识别系统设计(论文)_kaic

摘 要 智能垃圾分类技术逐渐受到了政府的重视和支持&#xff0c;越来越多的城市开始推行垃圾分类政策。因此设计一款能够对垃圾进行识别并分类的控制系统具有一定的现实意义。本设计采用STM32单片机作为整个系统的控制核心&#xff0c;利用K210开发板作为图像识别控制系统&…

在Postgres中,如何有效地管理大型数据库的大小和增长

文章目录 一、定期清理和维护1. VACUUM和ANALYZE2. 删除旧数据和归档 二、分区表三、压缩数据四、配置优化1. 调整维护工作负载2. 监控和日志 五、使用外部存储和扩展1. 外部表和FDW2. 扩展和插件 六、定期备份和恢复测试结论 管理大型数据库的大小和增长是数据库管理员&#x…

如何看懂电路图,理解电流回路

任何电器都需要电源来供电。电源有正极(+)和负极(-),为了向负载提供电力,电流必须从正极流出,通过负载后再回到负极。这构成了一个供电电流回路,负载得到电力供应后才能开始工作。如果其中的某个环节断开,就无法形成供电电流回路,负载将得不到供电,也无法正常工作。 在一…

Typescript 总结3——类

一、是什么 类&#xff08;Class&#xff09;是面向对象程序设计&#xff08;OOP&#xff0c;Object-Oriented Programming&#xff09;实现信息封装的基础 类是一种用户定义的引用数据类型&#xff0c;也称类类型 传统的面向对象语言基本都是基于类的&#xff0c;JavaScript …

机器学习与深度学习 --李宏毅(笔记与个人理解)Day 20

Day 20 RNN 2 实际使用和其他应用 在实际的学习&#xff08;training&#xff09;过程中是如何工作的&#xff1f; step 1 Loss step 2 training Graindent Descent 反向传播的进阶版 – BPTT CLIpping 设置阈值~ 笑死昨天刚看完关伟说的有这玩意的就不是好东西 Why&#xff1…

window轻松使用k8s

Docker Desktop安装篇 1、win安装 1、下载安装包 https://www.docker.com/products/docker-desktop/ 官网下载安装包 2、配置win支持虚拟化 不勾选Hyper-V&#xff0c;它和Windows Subsystem for Linux (WSL) 是两套功能&#xff0c;这里不选他 3、安装WSL配置window支持lin…

2024电容笔专业对比评测:西圣、倍思、绿联哪款平替电容笔更好用?

在当今学习和工作环境中&#xff0c;iPad作为一种多功能的学习和生产力工具&#xff0c;受到越来越多人的青睐与需求。然而&#xff0c;要充分发挥iPad的功能&#xff0c;一个优质的电容笔是必不可少的配件之一。电容笔不仅可以帮助用户进行手写笔记、绘画创作&#xff0c;还能…

包装类的认识

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x1…

48.基于SpringBoot + Vue实现的前后端分离-雪具销售系统(项目 + 论文PPT)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的雪具销售系统设计与实现管理工作系统…

探索分布式系统监控zabbix-------------监控Windows

扩展windows 10 server2012 server2016 server2019 监控 一、在虚拟机中安装zabbix的客户端 下载网站 Download and install Zabbix 安装系统一直托不进虚拟机中&#xff1b;因为没安装Tools组件 点击虚拟机&#xff0c;选择安装VMware Tools 查看主机名 二、在web页…

ArcGIS在洪水灾害普查、风险评估及淹没制图中的技术应用

2020年国务院办公厅印发《关于开展第一次全国自然灾害综合风险普查的通知》&#xff0c;定于2020年至2022年开展第一次全国自然灾害综合风险普查。水旱灾害风险普查是全国自然灾害综合风险普查的重要组成部分。其中&#xff0c;我国有超过 60%的国土面积、90%以上的人口均受到不…

FFmpeg: 自实现ijkplayer播放器--01项目简介

文章目录 项目介绍流程图播放器实现过程界面展示项目代码 项目介绍 此项目基于FFmeg中 ffplay.c进行二次开发&#xff0c;实现基本的功能&#xff0c;开发软件为Qt 项目优势&#xff1a; 参考ijkplayer播放器&#xff0c;实现UI界面和播放器核心进行解耦&#xff0c;容易添加…

SpringBoot3 函数式web 小记

说明&#xff1a;函数式web是spring5.2之后的一个新特性&#xff0c;Spring Boot 3 进一步优化了这一模型&#xff0c;为开发现代 Web 应用提供了更加灵活、简洁的方法&#xff1b; 函数式web的四大核心对象 - RouterFunction&#xff1a;定义路由信息 - RequestPredicates&am…

15_SpringBoot

文章目录 SpringBoot创建SpringBoot应用官网IDEApom.xml文件启动类 整合SpringMVC整合配置类静态资源处理FilterTomcat其他配置 整合MyBatis约定大于配置的原理配置文件中的值的获取yml形式的配置文件约定大于配置的说明注解配置文件配置项 SpringBoot SpringBoot简化Spring阶…

强化网络安全防线,您的等级保护措施到位了吗?

在这个信息化飞速发展的时代&#xff0c;网络安全已经成为我们每个人都需要关注的问题。无论是企业还是个人&#xff0c;我们的工作和生活都越来越依赖于网络。确保网络环境的安全&#xff0c;防止信息泄露和网络攻击&#xff0c;已经成为了一项至关重要的任务。等级保护制度作…

现货白银的止损:原始止损和移动止损

止损是我们做现货白银必备的工具&#xff0c;它的主要功能是控制投资者的亏损&#xff0c;进而控制我们在交易中的风险。而现货白银的止损主要有两种&#xff0c;一个是原始止损&#xff0c;另外一个是移动止损。 原始止损是我们现货白银止损的基本方法。原始止损的意思就是初次…

Git回滚版本并push到远端master

1、查看日志 git log 2、还原最近的版本 () --git reset --hard commit-id 如&#xff1a;git reset --hard d84da14bf2743683eca7a015f56114faaa344f42 3、覆盖分支版本 git push -f origin dev 回滚本地master完成后&#xff0c;将回滚后的代码push到远端master&#xf…

C++ | Leetcode C++题解之第25题K个一组翻转链表

题目&#xff1a; 题解&#xff1a; class Solution { public:// 翻转一个子链表&#xff0c;并且返回新的头与尾pair<ListNode*, ListNode*> myReverse(ListNode* head, ListNode* tail) {ListNode* prev tail->next;ListNode* p head;while (prev ! tail) {ListN…