作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
西蒙·斯特拉顿的头像

西蒙Stratton

西蒙已经做了18年的技术测试员. 他从IBM开始,转到EADS,然后是富士通,现在经营着自己的公司.

Previously At

IBM
Share

Every year, 测试自动化工程师 来自世界各地的团队将研究最新的工具和技术,以使他们的测试自动化框架更加稳定, faster, 更容易使用和维护. 这对于确保他们的框架在公司内被持续广泛采用是至关重要的. 一般来说,臃肿、过时的框架很快就会过时.

在本文中, 我们将看看你可以更新2019年框架的一些方法,以及如何为2020年做准备. 为了改进我的框架,我总是专注于“痛点”.“这些都是设置复杂或导致最多失败的领域. 我确定了我想要简化或改进的三个主要领域:

  1. 硒网格
  2. Waits
  3. Chrome DevTools

硒网格的设置是出了名的棘手,并且可能在没有警告的情况下失败. 我想看看这里有什么进步,如果有的话. 我还想调查一下是否有新的 waits 已添加到Selenium API以提高我创建的任何测试的稳定性. Finally, 我想看看是否可以通过Selenium开始与Chrome DevTools进行交互, 哪些已经成为任何测试人员工具包的重要组成部分.

技巧1:Dockerize你的Selenium网格

众所周知,硒网格很难设置, unstable, 而且很难部署, 或者版本控制, 在CI管道上. 一种更简单、稳定和可维护的方法是使用预构建的Selenium Docker映像.

Note: 这种方法的一个缺点是不支持IE (Internet Explorer), 因为目前还不可能将Windows操作系统容器化.

准备就绪

要开始运行,首先你需要 Docker and 码头工人组成 安装在您的机器上. 如果你运行的是Windows 10或Mac,那么它们都将通过 码头工人的桌面.

开始你的网格

Docker Hub上的官方Selenium存储库包含 预构建的Docker镜像 用于您的Selenium Hub和Firefox和Chrome节点.

在本地硒网格中使用它们的最简单方法是在项目的根目录中构造一个码头工人组成文件. Name the file docker-compose.yml 为了让事情简单化.

我在下面包含了一个创建如下网格的例子:

  • 单个Selenium Hub
  • 一个Chrome节点
  • Firefox节点1个
# docker-compose.yml
version: "3"
services:
  selenium-hub:
	图片:硒/中心:3.141.59-neon
	container_name: selenium-hub
	ports:
  	- "4444:4444"
  chrome:
	图片:硒/ node-chrome: 3.141.59-neon
	volumes:
  	- /dev/shm: / dev / shm
	depends_on:
  	——selenium-hub
	environment:
  	- HUB_HOST = selenium-hub
  	——HUB_PORT = 4444
  firefox:
	图片:硒/ node-firefox: 3.141.59-neon
	volumes:
  	- /dev/shm: / dev / shm
	depends_on:
  	——selenium-hub
	environment:
  	- HUB_HOST = selenium-hub
  	——HUB_PORT = 4444

码头工人组成文件描述了网格的设置. 有关创建码头工人组成文件的更多信息,请参阅 官方文档.

要启动网格,只需使用任何终端窗口(a powershell or cmd 在项目的根目录下运行以下命令:

docker-compose起来

连接到电网

您可以以与通常完全相同的方式连接到硒网格, 因为集线器正在监听本地机器的端口4444. 这里有一个例子,我们设置我们的驱动程序使用我们的Chrome节点.

// Driver.java
保护静态RemoteWebDriver浏览器;
DesiredCapabilities cap = new DesiredCapabilities();
ChromeOptions = new ChromeOptions();
           	 
cap.setCapability (ChromeOptions.能力,chromeOptions);           	 
cap.setBrowserName(“铬”);
           	 
driver = new RemoteWebDriver(cap);

然后你可以使用 TestNG 库,以便像往常一样在多个节点上并行运行测试.

值得注意的是,可以在每个节点上运行多个浏览器. 但是这是不鼓励的, 每个节点使用一个浏览器被认为是实现最佳性能的最佳实践.

其他提示和技巧

如果您想查看浏览器上发生了什么,以便调试您的测试, 那就值得拥有 debug 你的版本 docker-compose.yml 文件,下载 debug browser nodes. 其中包含一个VNC服务器,因此您可以在测试运行时观察浏览器.

为了提高速度(通常的方式),也可以直接运行浏览器,Selenium也提供了这一功能 base 映像的版本,以便在需要安装其他软件时构建自己的映像.

为您的CI管道创建一个稳定版本的Grid, 也可以将网格部署到 Kubernetes或Swarm. 这确保了任何docker在发生故障时都能快速恢复或替换.

技巧2:聪明地等待

As any 测试自动化工程师 knows, waits 对测试自动化框架的稳定性至关重要吗. 它们还可以通过渲染任意属性来加快测试速度 sleeps or pauses 冗余和克服缓慢的网络和跨浏览器的问题. 下面是一些让你的 waits 更有弹性.

Java自动化测试教程#2:等待中的逻辑运算符:指定等待

The ExpectedConditions 阶级随着时间的推移而发展,现在几乎涵盖了所有可以想象到的情况. While ExpectedConditions.presenceOfElementLocated(定位) 中的方法通常是最佳实践 ExpectedCondition 类来覆盖每个用户操作,方法是将它们嵌入到 Actions.java class. 这将使你的测试免受大多数跨浏览器或慢速网站问题的影响.

For example,如果单击链接会打开一个新的选项卡,则使用 ExpectedConditions.numberOfWindowsToBe (2). 这将确保选项卡在尝试切换到它之前就在那里.

你也可以用a wait 以确保在使用时捕获页面上显示的所有元素 findElements. 这在需要时间的情况下尤其有用 search 页返回其结果. 例如,这一行:

List results = driver.findElements(定位器.RESULTS);

它可能导致空 List 如果您的搜索结果尚未加载,则使用. 相反,最好使用 numberOfElementsToBeMoreThan 等待结果大于零的预期条件. For example:

WebElement searchButton = driver.findElement(定位器.SEARCH_BUTTON);
searchButton.click(); 

新的WebDriverWait(driver, 30)	
	.直到(ExpectedConditions
		.numberOfElementsToBeMoreThan(定位器.RESULTS, 0)); 

List results = driver.findElements(定位器.RESULTS);
results.get(0).click();

Now, your findElements 命令只会在搜索结果返回后运行.

This wait 在处理不能很好地与Selenium (e.g.、Angular网站). 创建这样的方法将保护您的测试,使它们更加稳定.

受保护的静态web元素waitforeelement (By locator){    
	try {        
		新建WebDriverWait(浏览器,30)                
			.直到(ExpectedConditions                
				.numberOfElementsToBeMoreThan(定位器,0));    
	} catch (TimeoutException){        
		e.printStackTrace ();            
		Assert.超时:元素在“+ WAIT +”秒内找不到!");    
	} catch(异常e){              
		e.printStackTrace ();        
		Assert.失败(“出了问题!");    
	}    
	返回浏览器.findElement(定位);    
}

甚至可以等待元素不再可见. 如果您在单击后等待弹出窗口消失,则此功能特别有用 OK or Save 按钮,然后继续测试.

WebElement okButton = driver.findElement(定位器.OK_BUTTON);
okButton.click();
 
新的WebDriverWait(driver, 30)
	.until(
		ExpectedConditions
			.invisibilityOfElementLocated(定位器.POPUP_TITLE)
);

上面描述的所有方法以及更多的方法都在 官方文档. 花十分钟阅读所有的可能性并提高框架的稳定性是非常值得的.

Java自动化测试教程#2:等待中的逻辑运算符

一个很好的方法来建立你的韧性 waits 是通过使用逻辑运算符吗. For example, 如果你想检查一个元素是否已经被定位并且它是否可以点击, 您将使用以下代码(请注意,这些示例返回一个布尔值):

wait.直到(ExpectedConditions.and(               
	ExpectedConditions.presenceOfElementLocated(定位),                	
	ExpectedConditions.elementToBeClickable(定位)
	)
);

如果不确定页面的标题是否会更改,则使用OR操作符比较合适. 然后,如果第一个条件失败,您可以包含对URL的检查, 来确认你在正确的页面上.

wait.直到(ExpectedConditions.or(                
	ExpectedConditions.titleIs (expectedTitle),                 
	ExpectedConditions.urlToBe (expectedUrl)
	)
);

或者,如果您希望确保在页面上执行操作后不再启用复选框, 那么NOT操作符是合适的.

wait.直到(ExpectedConditions.not(
	ExpectedConditions.elementToBeClickable(定位)
	)
);

使用操作符可以使您 waits 更有弹性,测试结果不那么脆弱.

提示#3:Chrome DevTools:模拟网络条件

运行你的web应用 localhost 或者在本地网络上运行时,会给人一种错误的印象. 节流各种上传和下载速度的能力将使您能够更好地表示您的应用程序如何在互联网上运行, 在什么情况下超时会导致操作失败. 我们可以开始模拟使用Chrome的DevTools的力量.

下面的代码将使用不同的下载和上传速度打开Toptal主页. 首先,我们将使用以下代码将我们的速度存储在TestNG数据提供程序中:

import org.testng.annotations.DataProvider;

公共类ExcelDataProvider {

		@DataProvider(name = "networkConditions")
    [][] networkConditions()抛出异常{
        返回新对象[][]{
						//上传速度、下载速度(kb/s)和延迟(ms).
            { 5000 , 5000, 5 },
            { 10000, 7000, 5 },
            { 15000, 9000, 5 },
            { 20000, 10000, 5 },
            { 0, 0 },
        };
    }
}

Note: 上传和下载限制生效了 kb/s 然后是潜伏期 ms.

然后,我们可以使用这些数据在不同的网络条件下运行我们的测试. 在测试中, CommandExecutor 会在浏览器的当前会话中执行该命令吗. 这反过来将激活必要的设置 Chrome的开发者工具 模拟慢速网络的功能. 中的代码 if 语句可以包含在 @BeforeClass 在运行一组测试时使用.

import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.Response;

公共类TestClass {

//加载我们的数据提供程序
@Test(dataProvider = "networkConditions")
公共void测试(int下载,int上传,int延迟)
抛出IOException {

        //仅在网络受限时运行
        if (download > 0 && upload > 0) {
                CommandExecutor executor = driver.getCommandExecutor ();

                //创建所需网络条件的hashmap
                Map = new HashMap();
                //你甚至可以测试'离线'行为
                map.把(“离线”,假);
                map.把(“延迟”,延迟);

                map.把(“download_throughput”,downloadThroughput);
                map.把(“upload_throughput”,uploadThroughput);

                //执行代码
                Response = executor.execute(
                        新命令(司机.getSessionId (),
                                    “setNetworkConditions”,
                                    ImmutableMap.(“network_conditions ImmutableMap.copyOf(地图))));
        }

        //打开网站
        driver.get (" http://mjq.daves-studio.com/");

        //然后你可以检查元素是否被加载等等.
        //不要忘记使用wait!
}
}

额外提示:如何管理你的Cookies

浏览器cookie可能会导致应用程序中的不同行为, 取决于它们是否从上一个会话中保存(例如.g.,应用程序可能在用户已经登录时加载). 在每次测试运行之前清除cookie是一种很好的做法,以确保它们不会引起问题.

下面的代码允许您删除所有cookie:

driver.manage().deleteAllCookies ();

您也可以通过名称删除cookie:

driver.manage().deleteCookieNamed(“CookieName”);

或者获取cookie的内容:

String myCookie = driver.manage().getCookieNamed(“CookieName”).getValue(); 

或者得到所有的饼干:

List cookies = driver.manage().getCookies();

2020年的测试自动化:展望未来

Selenium 4将在接下来的几个月发布. 它还在开发中, 但是作为一个alpha版本已经发布了, 值得一看的是,它将提供哪些改进.

Note: 您可以通过查看 roadmap.

W3C WebDriver标准化

No longer will Selenium need to communicate with the browser through the JSON wire protocol; instead, 自动化测试将直接与浏览器通信. 这应该可以解决Selenium测试出了名的不稳定特性, 包括防止浏览器升级. 希望测试速度也能提高.

一个更简单的Selenium网格

在Selenium 4中,硒网格将更加稳定,更易于设置和管理. 用户将不再需要分别设置和启动集线器和节点,因为网格将充当节点和集线器的组合. Plus, 将会有更好的Docker支持, 并行测试将包括在本地, 它将提供一个更丰富的用户界面. 使用Hooks的请求跟踪还将帮助您调试网格.

Documentation

Selenium文档将得到急需的全面修改, 自Selenium 2发布以来就没有更新过.0.

API的更改

对Opera和PhantomJS浏览器的支持将被移除. 无头运行可以用Chrome或Firefox执行, 而且Opera是基于Chromium构建的,因此对这款浏览器进行Chromium测试就足够了.

WebElement.getSize() and WebElement.getLocation() 现在被单一方法取代了吗 WebElement.getRect(). However, 因为这些通常用于创建单个元素的屏幕截图, 值得知道的是,在Selenium 4中还会有一个API命令来捕获元素的屏幕截图.

For WebDriver Window, the getPosition and getSize 方法将被 getRect 方法和 setPosition and setSize 方法将被 setRect method. fullscreen and minimize 方法是可用的,因此这些操作可以在您的测试中执行.

其他显著变化:

  • The Options 类现在将扩展 Capabilities class.
  • A driver.switchTo().parentFrame() 方法使框架导航更容易.
  • nice 定位器将被包括在一个比当前的更高的层次上运行. 它们将是的子类 By.
  • 将会有一个实现 DevTools API, 允许用户利用Chrome调试协议(以及其他浏览器上的等效协议)提供的功能。. 这些包括:
    • 全页截图(包括屏幕外元素).
    • 流日志.
    • 等待页面上的突变事件.
  • 许多已弃用的方法和类也将被删除.

Note: 你可以得到一个 Selenium 4的Alpha版本 从Maven存储库中. 强烈建议您在当前框架(理想情况下是在沙盒分支上)上进行测试。, 所以你已经准备好改变了.

Conclusion

在本文中, 我已经介绍了几个改进测试自动化框架的领域. 它现在比以前更加稳定和可用, 哪个将对软件交付生命周期中涉及的每个人产生积极的影响.

做出我上面列出的改变是一个好的开始, however, 我强烈建议您检查整个框架的“痛点”,因为你可以做一些我没有提到的改进. 例如,你是否使用 WebDriver经理 来管理您的驱动程序,或者您仍然手动更新它们?

我还建议每年至少定一个这样做的日期, 虽然最理想的是每六个月一次. 在本文中,我包含了Selenium 4中即将发生的更改.0. 请务必阅读 alpha 版本的Selenium. 变化将是戏剧性的,你需要做好准备. 我希望这对你有用. 如果您在对框架进行春季大扫除时发现了任何新的方法或技术, 请将它们添加到下面的评论部分,与本博客的其他读者分享.

Also, 如果您想了解Selenium中的自动化测试, 以及如何使用Page Object模型来编写可维护和可重用的测试例程, check out Selenium中的自动化:页面对象模型和页面工厂.

了解基本知识

  • 在Java测试自动化框架中,等待和睡眠的区别是什么?

    在执行一些代码之前,Sleep总是会暂停一段时间, 而wait只会暂停执行,直到出现预期的条件或超时, 先到者为准. 您不应该在测试自动化框架中使用sleep,因为您希望测试尽可能快地运行.

  • 什么是Java中的测试?

    这是当您使用Java编程语言创建自动化测试时.

  • 如何用Java编写自动化测试用例?

    为了编写在浏览器中运行功能测试的web应用程序的自动化测试用例, 您必须使用像Selenium库这样的工具, 正如我们在本文中所做的那样. 您还需要使用测试框架,如TestNG或JUnit.

  • Java中有哪些测试框架可用?

    您可以使用许多测试和断言框架来运行selenium驱动的自动化测试. 我使用TestNG是因为它是专门为验收测试设计的, 而像JUnit这样的框架通常用于单元测试. 另一个值得研究的伟大框架是Spock,因为它具有很强的表现力并且易于阅读. Google的Truth断言库也是编写可读测试的好方法.

聘请Toptal这方面的专家.
Hire Now
西蒙·斯特拉顿的头像
西蒙Stratton

Located in 卡迪夫,英国

Member since May 21, 2019

作者简介

西蒙已经做了18年的技术测试员. 他从IBM开始,转到EADS,然后是富士通,现在经营着自己的公司.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Previously At

IBM

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® community.