使用 Selenium Grid2 来提高全球化测试中自动化截图的执行效率

转载 2015年07月08日 11:02:15

全球化测试的目的是检测产品设计中可能阻碍全球化的潜在问题,而翻译验证测试 (Translation Verification Test - TVT) 是全球化测试中一个非常重要的部分, 针对 Web 应用界面的 TVT 我们通常采用基于 Selenium WebDriver 框架的程序进行自动化截图来帮助翻译测试人员验证翻译质量。在使用 Selenium WebDriver 的过程中, 我们发现在同一台机器上截取多国语言截图效率太低, 同时还会有一些准确度的差错。因此通过 Selenium Grid2 将截图任务分发给不同语言的测试环境再进行测试很有必要。

在持续交付模式下的全球化测试对自动化测试的挑战

挑战

在 2014 年 3 月, 我们所测试的产品正式进入 Continuous Delivery 的开发模式,从每三个月发布一次产品转变为每个月发布一次产品。这很大程度上压缩了我们用来准备和执行全球化测试的时间,对于项目组测试成员的技术能力和对产品熟悉程度是一种挑战。我们在 TVT 准备过程中,需要在短时间内, 将不同语言的界面截图归档保存并发送给翻译验证测试人员。过多的手动操作使我们很难专注于分析和发现全球化问题,项目组考虑采用自动化截图来取代原有的操作。

改进

在我们全面采用 Selenium WebDriver 进行自动化截图后,对结果不太满意。一方面, 受制于测试机器的性能,我们无法在一台测试机器上并行执行多语言的自动化截图; 另一方面,曾经有翻译验证测试人员向我们反映在截图中字体存在问题,解决方法是需要安装系统语言包并且将系统语言切换成特定语言的操作系统重新进行截图。我们决定采用 Selenium 套件中的 Grid2 将测试分布到特定测试机器中进行测试。

Selenium Grid 简介

Selenium-Grid 允许你在不同的测试机器上同时执行相同的测试。从全球化测试的角度可以理解为将不同语言的测试分布在不同的测试机器上运行。这样测试的好处在于可以得到最符合语言环境的截图,同时还能减少执行时间。

Selenium-Grid 同样支持在不同的浏览器环境上执行相同的测试。比如说,我们分别在三台机器上安装 IE,Firefox,和 Chrome,然后将测试分布在三台机器上同时执行,就可以测试软件在不同浏览器上的全球化支持情况。

Selenium-Grid 分为 1.0 和 2.0 个版本。1.0 提供对 SeleniumRC 的支持,在一些遗留系统中可能还是以 1.0 版本为主;2.0 版本则对目前的 WebDriver 提供支持,在本文中我们将重点针对 Selenium-Grid 2.0 进行介绍。本文中开发环境采用 Java 语言,浏览器以 Firefox 为主。整个测试过程将不采用 Junit 或者 TestNG 测试框架,而是采用 Java 代码实现多线程测试环境。

使用 Selenium WebDriver 进行自动化截图的实现

启动 Selenium Grid2

通过以下命令启动 Selenium Grid2 控制器。控制器可以接受所有的控制请求并将测试分布到合适的 Grid 节点。为防止 Java 内存溢出,可以设置虚拟内存的用量。

清单 1. 启动控制器
java -Xms1600m -Xmx1600m -jar "C:\dev\selenium-server-standalone-2.42.1.jar" -role hub

通过以下命令启动 Selenium Grid2 节点,启动 Grid 节点时需要告知控制器的位置。在全球化测试中,一个节点可以理解为一个独立语言版本的操作系统,上面安装有独立语言版本的 Firefox 浏览器。

清单 2. 启动 Grid 节点
java -jar "C:\dev\selenium-server-standalone-2.42.1.jar" -role node -hub,
	http://SXV2V668:4444/grid/register -port 5556

当我们需要针对 14 个国家不同语言进行全球化测试时,我们可以将对应语言环境的操作系统作为节点连接到 Selenium Grid2。当运行自动化测试代码时,不同节点上的浏览器会被切换成符合语言环境的设置,并同步开始对需要测试的软件执行测试代码,从而提高执行效率。Selenium Grid2 的构架图如下,首先需要启动 Grid 控制器,然后启动多个指向该控制节点的远程 Grid 节点。

图 1. Selenium Grid 构架图
图 1. Selenium Grid 构架图

当测试程序运行时,测试代码会被并发的发送给控制器,然后由控制器决定发送到指定的控制节点执行测试。当某个节点无法获取的情况, 测试程序需要告知控制器可以使用的备用节点。

图 2. Selenium Grid2 测试程序序列图
图 2. Selenium Grid2 测试程序序列图

实现在 Grid2 中执行并行测试

  1. 在 Eclipse 中创建一个 Maven 项目,并将 Selenium 的支持包添加到 pom.xml。由于 Maven 自身的特性,添加成功的依赖包会自动从 Maven Repository 获取相关的 Jar 包并添加到项目的库中。
图 3. 在 Eclipse 图形界面添加正确的依赖包
图 3. 在 Eclipse 图形界面添加正确的依赖包
  1. 成功的添加依赖包后可以在项目目录中查看所有导入的 Java 库,其中 Maven Dependencies 中可以看到 Selenium-*.jar 的库文件。这里值得一提的是,在实际测试中,我们发现旧版本 Selenium 库有可能和浏览器发生不兼容的现象,因此请尽量保证这里的 Selenium 库在 2.4.0 以上。
图片 4. Eclipse Project 的项目结构
图片 4. Eclipse Project 的项目结构
  1. 创建一个 Java 类,名称为 geniueTestCase.java,并实现 Runnable 接口。我们可以将平时使用的 FirefoxDriver 相关的测试代码导入到 geniueTestCase.java 文件中。
图片 5. 创建 geniueTestCase.java
图片 5. 创建 geniueTestCase.java
  1. 需要注意的是 FirefoxDriver 不支持远程运行,我们需要对代码进行修改。我们首先需要创建DesiredCapabilities对象来定义浏览器版本和操作系统,然后在申明RemoteWebDriver实例时将DesiredCapabilities对象传递给构造函数的变量。
清单 3. 实例化 RemoteWebDriver
private void init() throws MalformedURLException {
		if (driver == null) {
		DesiredCapabilities dc =DesiredCapabilities.firefox();
		dc.setCapability(FirefoxDriver.PROFILE, profile);
		try{
		synchronized (RemoteWebDriver.class){
		driver = new RemoteWebDriver(new URL(nodeUrl), dc);
		}
			}catch(org.openqa.selenium.remote.UnreachableBrowserException e){
			System.out.println(nodeUrl+ "无法连接, 切换到备份节点");
			driver = null; this.nodeUrl = SystemConstant.LangCode.EN.getNodeURL();
			init();
			}catch(org.openqa.selenium.WebDriverException e){
			System.out.println(nodeUrl+ "异常, 切换到备份节点");
			driver = null;
			this.nodeUrl = SystemConstant.LangCode.EN.getNodeURL();
			init();
			}
		}
	}
  1. 将现有的 Selenium Grid2 节点和对应的语言环境放在枚举实例中,这样在自动化测试过运行某个特定语言环境的测试代码时,就可以很容易获取指定节点,同时也提高了代码的可读性。
清单 4.LangCode 枚举类
public class SystemConstant{ 
public enum LangCode{
	CN("zh-cn", "http://SXV2V668:5557/wd/hub"), TW("zh-tw",
	"http://SXV2V670:5557/wd/hub"), DE("de-de",
	"http://SXV2V664:5557/wd/hub"), CS("cs",
	"http://SXV2V672:5557/wd/hub"), ES("es-es", "http://SXV2V669:5557/wd/hub"), RU("ru",
	"http://SXV2V675:5557/wd/hub"), JP("ja",
	"http://SXV2V666:5557/wd/hub"), KO("ko",
	"http://SXV2V667:5557/wd/hub"), HU("hu",
	"http://SXV2V673:5557/wd/hub"), PL("pl",
	"http://SXV2V674:5557/wd/hub"), TH("th",
	"http://SXV2V671:5557/wd/hub"), IT("it-ch",
	"http://SXV2V665:5557/wd/hub"), PTBR("pt-br",
	"http://SXV2V662:5557/wd/hub"),FR("fr",
	"http://SXV2V663:5557/wd/hub");
private String locale, nodeURL;
LangCode(String locale, String nodeURL) { 
		this.locale = locale; this.nodeURL = nodeURL;
			}
public String getLocale() {
		return locale; 
    }
public void setLocale(String locale) {
		this.locale = locale;
    }
public String getNodeURL() {
		return nodeURL;
    }
public void setNodeURL(String nodeURL) {
		this.nodeURL = nodeURL;
    } 
@Override
public String toString() {
		return locale + " at " + nodeURL;
    }
  }
}
  1. 在 main 中添加以下代码就可以让 Test Case 在简中、繁中、日语的环境上并行测试。由于 geniueTestCase 本身通过实现 Runnable 接口来创建线程,增加了程序的健壮性,代码可以被多个线程共享,同时线程中代码和数据有效分离,提高了代码的可维护性。在实际运行中,RemoteWebDriver 的实例化会消耗比较多的 CPU 时间, 多个线程同时初始化程序也可能会抛出异常。然而我们可以将 RemoteWebDriver 的实例化包含在 synchronized (RemoteWebDriver.class) 代码同步块中,以保证在同一时刻只有一个线程可以对 RemoteWebDriver 进行实例化,但是实际测试运行的顺序和线程启动的顺序可能还是会有些差别。
清单 5.在多个 Grid 节点执行远程测试
public static void main(String[] args) throws MalformedURLException,
				InterruptedException {
		List<geniueTestCase> testList = new ArrayList<geniueTestCase>();
		String url = "http://9.110.79.148:8080";
		String hubUrl = "http://9.115.47.65:4444/wd/hub";
		testList.add(new geniueTestCase("C:\\dev\\firefox", url,
						SystemConstant.LangCode.EN.getNodeURL(),hubUrl,
						SystemConstant.LangCode.EN.getLocale()));
		testList.add(new geniueTestCase("C:\\dev\\firefox", url,
						SystemConstant.LangCode.CN.getNodeURL(),hubUrl,
						SystemConstant.LangCode.CN.getLocale()));
		testList.add(new geniueTestCase("C:\\dev\\firefox", url,
						SystemConstant.LangCode.TW.getNodeURL(),hubUrl,
						SystemConstant.LangCode.TW.getLocale()));
		testList.add(new geniueTestCase("C:\\dev\\firefox", url,
						SystemConstant.LangCode.JP.getNodeURL(),hubUrl,
						SystemConstant.LangCode.JP.getLocale()));
		for (geniueTestCase e : testList){
				new Thread(e).start();
		}
	}

结束语

对于我们全球化测试部门来说,拥有一套符合产品特点的自动化测试框架有百益而无一害。从我们 2014 年 4 月份开始使用自动化截图到现在使用 Grid2 来进行并行自动化截图,我们的执行效率相对于原来提升了 2 倍,我们也帮助产品组在一年内成功的交付了支持全球化的 15 个版本的软件产品。

如果大家感兴趣,可以参考本文的代码下载,尝试将自己的自动化测试代码改写成拥有远程并行测试的强大功能。

下载

描述 名字 大小
参考代码下载 seleniumASSP.zip 151k

参考资料

学习


相关文章推荐

使用自动化测试框架selenium,批量的进行截图

最近在做一个自动化的电子邮件系统,实现是在outlook客户端能够接受html的邮件。 但是,由于我做的报表使用fusioncharts做的,fusioncharts框架是一个js图表库,所有的图表都...

如何搭建Selenium-Grid2环境(Java)(自动化测试技术)

Selenium对于我们进行web自动化测试有很大的帮助,如果要进行大范围的测试覆盖,就不能仅仅在一两台机器上跑了;同样Selenium-Grid也给我们提供了这样的帮助,我们可以借助Selenium...

Selenium Grid2分布式执行测试脚本

Selenium grid是用来分布式执行测试用例脚本的工具,比如测试人员经常要测试多浏览器的兼容性,那就可以用到grid了。下面就来介绍如何在多个浏览器上运行同一份脚本。...

Selenium-Grid工作方式(自动化测试技术)

转自:http://blog.csdn.net/five3/article/details/9428655 Selenium-Grid版本 selenium-grid分为版本1和版本2,其...

Docker与Web自动化测试:一键创建Selenium Grid集群

https://yq.aliyun.com/articles/8529 摘要: Docker的容器技术的优秀特性,例如秒级启动、应用隔离、良好的可移植性等,可以在DevOps中大显身手,并推动持...

Selenium自动化之截图保存现场

前提:   自动化中截图功能是直接呈现问题,帮助定位的一种很好的手段。   下面总结一下,我用Selenium做自动化是如何保留截图的。   环境和工具:   eclipse、...

利用 Selenium WebDriver + Grid2 实现并行的浏览器端性能测试

http://www.testwo.com/article/212 在 Web 2.0 应用中,页面装载时间和浏览器渲染时间将成为决定性能的关键因素。我们在测试过程中不仅需要手动触发性能...

Appium 多机并行执行测试(基于Selenium Grid)

Appium 多机并行执行测试(基于Selenium Grid)
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用 Selenium Grid2 来提高全球化测试中自动化截图的执行效率
举报原因:
原因补充:

(最多只允许输入30个字)