Selenium自动化测试用例设计注意事项(二)

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介:

UI映射

  一个UI映射是一种机制,它存储所有的定位器的测试套件在一个地方,方便修改UI元素的路径标识符或改变在AUT。测试脚本,然后使用UI地图定位以被测试的元件。基本上,UI地图是一个存储库的测试脚本对象,对应于被测试的应用程序的UI元素。

  是什么让一个UI地图有帮助吗?其主要目的是测试脚本的管理更加容易。当定位需要编辑,有一个中央位置轻松地找到对象,而不是通过搜索测试脚本代码。此外,它允许改变的标识符在一个地方,而不是在多个地方,以使更改在测试脚本,或为此事,在多个测试脚本。

  总之,一个UI地图有两个显着的优点。

  ● UI对象使用一个集中的位置,而不是让他们分散在整个脚本。这使得脚本维护更高效。

  ● 神秘的HTML标识符和名称可以被赋予了更多的人类可读的名字,提高测试脚本的可读性。

  考虑下面很难理解的测试代码(Java语言)。

public void testNew() throws Exception {
             selenium.open(http://www.test.com);
             selenium.type("loginForm:tbUsername", "xxxxxxxx");
             selenium.click("loginForm:btnLogin");
             selenium.click("adminHomeForm:_activitynew");
             selenium.waitForPageToLoad("30000");
             selenium.click("addEditEventForm:_IDcancel");
             selenium.waitForPageToLoad("30000");
             selenium.click("adminHomeForm:_activityold");
             selenium.waitForPageToLoad("30000");
}

  该代码很难被那些不熟悉待测应用(AUT)页面源代码的人理解。即使是待测应用的固定用户可能也很难理解这段脚本代码的作用。一个更好的脚本可能是:

public void testNew() throws Exception {
             selenium.open(http://www.test.com);
             selenium.type(admin.username, "xxxxxxxx");
             selenium.click(admin.loginbutton);
             selenium.click(admin.events.createnewevent);
             selenium.waitForPageToLoad("30000");
             selenium.click(admin.events.cancel);
             selenium.waitForPageToLoad("30000");
             selenium.click(admin.events.viewoldevents);
             selenium.waitForPageToLoad("30000");
}

  使用备注和空格换行、再加上UI映射标识,下面的代码更加易读:

public void testNew() throws Exception {
 
             // Open app url.
             selenium.open(http://www.test.com);
 
             // Provide admin username.
             selenium.type(admin.username, "xxxxxxxx");
 
             // Click on Login button.
             selenium.click(admin.loginbutton);
 
             // Click on Create New Event button.
             selenium.click(admin.events.createnewevent);
             selenium.waitForPageToLoad("30000");
 
             // Click on Cancel button.
             selenium.click(admin.events.cancel);
             selenium.waitForPageToLoad("30000");
 
             // Click on View Old Events button.
             selenium.click(admin.events.viewoldevents);
             selenium.waitForPageToLoad("30000");
}

  有多种方法可以实现UI映射。可以创建一个类或结构体来存储字符串变量,每个变量存储一个定位信息。或者,使用一个文本文件来存储键值对。在Java中,一个包含键值对的属性property文件可能是最好的方法。


 考虑如下属性文件prop.properties,为上述代码例子中的UI元素指定了 “别名”:

admin.username = loginForm:tbUsername
admin.loginbutton = loginForm:btnLogin
admin.events.createnewevent = adminHomeForm:_activitynew
admin.events.cancel = addEditEventForm:_IDcancel
admin.events.viewoldevents = adminHomeForm:_activityold

  其中定位信息还是指向页面的HTML对象,但我们在测试脚本和UI元素之间引入一层抽象层。测试类从属性文件中读取定位信息,从而实现UI映射。

  页面对象设计模式

  页面对象设计模式,可以提高自动化测试脚本的维护性、减少代码重复,越发流行。页面对象是一个面向对象的类,作为待测应用对外提供的接口。测试代码在需要和UI页面交互时,使用此页面对象类的方法。这样做的好处是,如果UI页面发生变化,测试代码本身并不需要改变,只需要改变相应的页面对象的代码。为适应新UI页面的所有更改,都位于一个地方。

  页面对象设计模式具有以下优点:

  1、测试代码和页面相关的代码,比如页面元素定位信息(若使用UI映射,也包括定位信息的应用),页面布局等,完全分离;

  2、可以维护单一的储存库来存储页面提供的服务或操作,而不是把他们分散在测试代码中。

  在这两种情况下,这使得任何由于UI界面变化导致的修改,都可以在一个地方进行修改。关于该技术的更多有用信息,可以在众多的博客上找到。我们也鼓励读者去阅读更多。 许多人写这样的设计模式和超出本用户指南的范围,可以提供有用的提示。不过,为了让你开始,我们将举例说明页面对象的一个简单的例子。

  首先,考虑一个例子,典型的自动化测试,不使用页面对象。

/***
 * Tests login feature
 */
public class Login {
 
        public void testLogin() {
                selenium.type("inputBox", "testUser");
                selenium.type("password", "my supersecret password");
                selenium.click("sign-in");
                selenium.waitForPageToLoad("PageWaitPeriod");
                Assert.assertTrue(selenium.isElementPresent("compose button"),
                                "Login was unsuccessful");
        }
}

  这种方法有两个问题。

  1、没有分离测试代码和待测应用的定位器(在这个例子中是ID);两者都交织在一个单一方法中。如果待测应用UI改变了它的标识,布局,或登录输入和处理的方式变化,测试代码本身必须改变。

  2、ID定位信息分散在多个测试代码中,所有的测试不得不使用此登录页面。

  使用页面对象技术,上述测试代码可以按如下方式重写,为登录页面的页面对象例子:

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
 
        private Selenium selenium;
 
        public SignInPage(Selenium selenium) {
                this.selenium = selenium;
                if(!selenium.getTitle().equals("Sign in page")) {
                        throw new IllegalStateException("This is not sign in page, current page is: "
                                        +selenium.getLocation());
                }
        }
 
        /**
         * Login as valid user
         *
         * @param userName
         * @param password
         * @return HomePage object
         */
        public HomePage loginValidUser(String userName, String password) {
                selenium.type("usernamefield", userName);
                selenium.type("passwordfield", password);
                selenium.click("sign-in");
                selenium.waitForPageToLoad("waitPeriod");
 
                return new HomePage(selenium);
        }
}


 主页的页面对象可能会是这个样子:

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
 
        private Selenium selenium;
 
        public HomePage(Selenium selenium) {
                if (!selenium.getTitle().equals("Home Page of logged in user")) {
                        throw new IllegalStateException("This is not Home Page of logged in user, current page" +
                                        "is: " +selenium.getLocation());
                }
        }
 
        public HomePage manageProfile() {
                // Page encapsulation to manage profile functionality
                return new HomePage(selenium);
        }
 
        /*More methods offering the services represented by Home Page
        of Logged User. These methods in turn might return more Page Objects
        for example click on Compose mail button could return ComposeMail class object*/
 
}

  现在,使用上述两个页面对象的登录测试代码,如下所示。

/***
 * Tests login feature
 */
public class TestLogin {
 
        public void testLogin() {
                SignInPage signInPage = new SignInPage(selenium);
                HomePage homePage = signInPage.loginValidUser("userName", "password");
                Assert.assertTrue(selenium.isElementPresent("compose button"),
                                "Login was unsuccessful");
        }
}

  怎么样使用页面对象进行设计有很大的灵活性,但也有一些基本的规则以保证得到测试代码具有所需的可维护性。页面对象本身不应该被验证或断言。这应该是测试的一部分,并应始终在测试代码中去验证或断言,而不要放在页面对象内。页面对象将包含页面展现,方法的形式表示页面提供的服务,但不需要包含应该在测试代码中维护的代码。

  唯一的应该存在页面对象中的验证方法是,验证页面、页面上的重要元素,被正确的加载。这这个验证应该在页面初始化时进行。在上面的例子中,SignInPage 和 HomePage 的构造函数检查了期望的页面是否可用,是否准备好接受测试代码的请求。

  页面对象并不一定要代表整个页面。页面对象设计模式可用于表示页面上组件。在待测应用上的一个页面若有多个组件,每个组件对应一个页面对象可以提高可维护性。

  在测试时,还会遇到其他的测试设计模式。有些人用一个页面工厂模式来实例化页面对象。讨论所有的这些测试模式,超出了本文档的的范围。在这里,我们只为大家介绍概念,使读者知道这些东西可以些什么。正如前面提到的,很多人都在博客上讨论这个话题,我们鼓励读者搜索这些话题。

  数据驱动测试

  数据驱动测试是指相同的测试(或测试集)可以使用不同的数据多次执行。这些数据集往往来自外部文件,如csv文件,文本文件,或者是从数据库加载。数据驱动测试是一种常用的自动化测试技术,使用不同的输入对应用程序进行多次验证。当测试被针对不同的数据进行设计时,所输入的数据就可以扩展,基本上不需要修改测试代码就可以进行更多的测试。

# Collection of String values
source = open("input_file.txt", "r")
values = source.readlines()
source.close()
# Execute For loop for each String in the values array
for search in values:
    sel.open("/")
    sel.type("q", search)
    sel.click("btnG")
    sel.waitForPageToLoad("30000")
    self.failUnless(sel.is_text_present("Results * for " + search))


 上面的Python代码打开一个文本文件,这个文件每行包含不同的搜索字符串。然后代码保存字符串到一个字符串数组,对数值进行遍历,使用搜索字符串进行查询,并进行断言。

  这是一个非常简单的例子,但其中的思路表明,可以很简单的使用编程、脚本语言进行数据驱动的测试。有关更多示例,请参阅 Selenium RC wiki 来了解如何从电子表格读取数据或使用TestNG的提供数据。此外,这是一个在自动化测试的专业人士圈内众所周知的话题之一,包括那些不使用Selenium的自动化圈子,因此搜索互联网上的“数据驱动测试”,会得到许多关于这一主题的博客。

  数据库验证

  另一种常见的测试类型是,比较用户界面上的数据和存储在后台数据库中的数据。因为你也可以使用一种编程语言进行数据库查询,假设你有数据库相关的函数,你可以用它们来检索数据,然后使用这些数据来验证页面上所显示的数据是正确的。

  考虑如下例子,从数据库中进行检索注册电子邮件地址,然后再和界面上的数据进行比较。代码如下,先建立一个数据库连接,并从数据库中检索数据,使用的是Java语言:

// Load Microsoft SQL Server JDBC driver.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
 
// Prepare connection url.
String url = "jdbc:sqlserver://192.168.1.180:1433;DatabaseName=TEST_DB";
 
// Get connection to DB.
public static Connection con =
DriverManager.getConnection(url, "username", "password");
 
// Create statement object which would be used in writing DDL and DML
// SQL statement.
public static Statement stmt = con.createStatement();
 
// Send SQL SELECT statements to the database via the Statement.executeQuery
// method which returns the requested information as rows of data in a
// ResultSet object.
 
ResultSet result =  stmt.executeQuery
("select top 1 email_address from user_register_table");
 
// Fetch value of "email_address" from "result" object.
String emailaddress = result.getString("email_address");
 
// Use the emailAddress value to login to application.
selenium.type("userID", emailaddress);
selenium.type("password", secretPassword);
selenium.click("loginButton");
selenium.waitForPageToLoad(timeOut);
Assert.assertTrue(selenium.isTextPresent("Welcome back" +emailaddress), "Unable to log in for user" +emailaddress)

  这是一个简单的Java例子从数据库中检索数据。








====================================分割线================================



最新内容请见作者的GitHub页:http://qaseven.github.io/

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
1月前
|
数据采集 测试技术 Python
自动化淘宝秒杀:使用Selenium WebDriver的实战指南
本文详细介绍了如何利用Selenium WebDriver自动化淘宝秒杀操作,包括环境配置、代码实现及注意事项,旨在帮助读者提升秒杀成功率,同时提醒合理使用以遵守平台规则。
82 8
|
2月前
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。
143 4
|
2天前
|
Web App开发 数据采集 JavaScript
CDP与Selenium相结合——玩转网页端自动化数据采集/爬取程序
本文介绍了Selenium、Chrome DevTools及Chrome DevTools Protocol (CDP) 的基本功能与应用。Selenium是一款开源自动化测试工具,适用于网页端应用程序测试和数据采集,具备跨平台特性。Chrome DevTools内置浏览器中,提供调试、分析Web应用程序的功能,包括元素、控制台、源代码和网络选项卡等。CDP是一套用于与Chromium内核浏览器通信的API,支持自动化测试和性能分析。文中还展示了Selenium与CDP结合使用的示例,如捕获网络请求数据和打印网页内容,并推荐了相关书籍和资源以供深入学习。
65 39
CDP与Selenium相结合——玩转网页端自动化数据采集/爬取程序
|
11天前
|
Web App开发 IDE JavaScript
Selenium IDE:Web自动化测试的得力助手
Selenium IDE:Web自动化测试的利器。作为开源工具,Selenium IDE支持录制与回放用户操作,适用于Chrome、Firefox等多浏览器,简化了测试流程,提升了效率,降低了自动化测试的门槛。它还支持导出多种编程语言的脚本,便于测试集成与复用。
61 19
Selenium IDE:Web自动化测试的得力助手
|
13天前
|
Web App开发 IDE 测试技术
Selenium:强大的 Web 自动化测试工具
Selenium 是一款强大的 Web 自动化测试工具,包括 Selenium IDE、WebDriver 和 Grid 三大组件,支持多种编程语言和跨平台操作。它能有效提高测试效率,解决跨浏览器兼容性问题,进行性能测试和数据驱动测试,尽管存在学习曲线较陡、不稳定等缺点,但其优势明显,是自动化测试领域的首选工具。
93 17
Selenium:强大的 Web 自动化测试工具
|
2月前
|
Java 测试技术 C#
自动化测试之美:从Selenium到Appium
【10月更文挑战第3天】在软件开发的海洋中,自动化测试如同一艘航船,引领着质量保证的方向。本文将带你领略自动化测试的魅力,从Web端的Selenium到移动端的Appium,我们将一探究竟,看看这些工具如何帮助我们高效地进行软件测试。你将了解到,自动化测试不仅仅是技术的展示,更是一种提升开发效率和产品质量的智慧选择。让我们一起启航,探索自动化测试的世界!
|
2月前
|
JavaScript 前端开发 测试技术
精通Selenium:从基础到高级的网页自动化测试策略
【10月更文挑战第6天】随着Web应用变得越来越复杂,手动进行功能和兼容性测试变得既耗时又容易出错。自动化测试因此成为了现代软件开发不可或缺的一部分。Selenium是一个强大的工具集,它支持多种编程语言(包括Python),允许开发者编写脚本来模拟用户与Web页面的交互。本文将带领读者从Selenium的基础知识出发,逐步深入到高级的应用场景,通过丰富的代码示例来展示如何高效地进行网页自动化测试。
500 5
|
2月前
|
Web App开发 IDE 测试技术
自动化测试的利器:Selenium 框架深度解析
【10月更文挑战第2天】在软件开发的海洋中,自动化测试犹如一艘救生艇,让质量保证的过程更加高效与精准。本文将深入探索Selenium这一强大的自动化测试框架,从其架构到实际应用,带领读者领略自动化测试的魅力和力量。通过直观的示例和清晰的步骤,我们将一起学习如何利用Selenium来提升软件测试的效率和覆盖率。
|
2月前
|
测试技术 Python
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
本文介绍了使用Python的unittest框架来加载测试用例的四种方法,包括通过测试用例类、模块、路径和逐条加载测试用例。
95 0
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
|
1月前
|
Web App开发 设计模式 JavaScript
自动化测试之美:如何利用Selenium实现Web应用的高效测试
【10月更文挑战第29天】在软件开发的世界中,测试是确保产品质量的关键步骤。本文将带你了解如何使用Selenium这一强大的自动化测试工具,提高Web应用测试的效率和准确性。通过实际案例,我们将探索Selenium的核心功能及其在现代软件开发中的应用,旨在帮助读者掌握自动化测试的精髓,从而提升软件测试工作的整体效能。
44 0
下一篇
DataWorks