作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Every year, 测试自动化工程师 来自世界各地的团队将研究最新的工具和技术,以使他们的测试自动化框架更加稳定, faster, 更容易使用和维护. 这对于确保他们的框架在公司内被持续广泛采用是至关重要的. 一般来说,臃肿、过时的框架很快就会过时.
在本文中, 我们将看看你可以更新2019年框架的一些方法,以及如何为2020年做准备. 为了改进我的框架,我总是专注于“痛点”.“这些都是设置复杂或导致最多失败的领域. 我确定了我想要简化或改进的三个主要领域:
硒网格的设置是出了名的棘手,并且可能在没有警告的情况下失败. 我想看看这里有什么进步,如果有的话. 我还想调查一下是否有新的 waits
已添加到Selenium API以提高我创建的任何测试的稳定性. Finally, 我想看看是否可以通过Selenium开始与Chrome DevTools进行交互, 哪些已经成为任何测试人员工具包的重要组成部分.
众所周知,硒网格很难设置, 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
为了让事情简单化.
我在下面包含了一个创建如下网格的例子:
# 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在发生故障时都能快速恢复或替换.
As any 测试自动化工程师 knows, waits
对测试自动化框架的稳定性至关重要吗. 它们还可以通过渲染任意属性来加快测试速度 sleeps
or pauses
冗余和克服缓慢的网络和跨浏览器的问题. 下面是一些让你的 waits
更有弹性.
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)
);
上面描述的所有方法以及更多的方法都在 官方文档. 花十分钟阅读所有的可能性并提高框架的稳定性是非常值得的.
一个很好的方法来建立你的韧性 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
更有弹性,测试结果不那么脆弱.
运行你的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://u67d.cqhmmg.com/");
//然后你可以检查元素是否被加载等等.
//不要忘记使用wait!
}
}
浏览器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();
Selenium 4将在接下来的几个月发布. 它还在开发中, 但是作为一个alpha版本已经发布了, 值得一看的是,它将提供哪些改进.
Note: 您可以通过查看 roadmap.
No longer will Selenium need to communicate with the browser through the JSON wire protocol; instead, 自动化测试将直接与浏览器通信. 这应该可以解决Selenium测试出了名的不稳定特性, 包括防止浏览器升级. 希望测试速度也能提高.
在Selenium 4中,硒网格将更加稳定,更易于设置和管理. 用户将不再需要分别设置和启动集线器和节点,因为网格将充当节点和集线器的组合. Plus, 将会有更好的Docker支持, 并行测试将包括在本地, 它将提供一个更丰富的用户界面. 使用Hooks的请求跟踪还将帮助您调试网格.
Selenium文档将得到急需的全面修改, 自Selenium 2发布以来就没有更新过.0.
对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
方法是可用的,因此这些操作可以在您的测试中执行.
其他显著变化:
Options
类现在将扩展 Capabilities
class.driver.switchTo().parentFrame()
方法使框架导航更容易.nice
定位器将被包括在一个比当前的更高的层次上运行. 它们将是的子类 By
.DevTools
API, 允许用户利用Chrome调试协议(以及其他浏览器上的等效协议)提供的功能。. 这些包括:
Note: 你可以得到一个 Selenium 4的Alpha版本 从Maven存储库中. 强烈建议您在当前框架(理想情况下是在沙盒分支上)上进行测试。, 所以你已经准备好改变了.
在本文中, 我已经介绍了几个改进测试自动化框架的领域. 它现在比以前更加稳定和可用, 哪个将对软件交付生命周期中涉及的每个人产生积极的影响.
做出我上面列出的改变是一个好的开始, however, 我强烈建议您检查整个框架的“痛点”,因为你可以做一些我没有提到的改进. 例如,你是否使用 WebDriver经理 来管理您的驱动程序,或者您仍然手动更新它们?
我还建议每年至少定一个这样做的日期, 虽然最理想的是每六个月一次. 在本文中,我包含了Selenium 4中即将发生的更改.0. 请务必阅读 alpha
版本的Selenium. 变化将是戏剧性的,你需要做好准备. 我希望这对你有用. 如果您在对框架进行春季大扫除时发现了任何新的方法或技术, 请将它们添加到下面的评论部分,与本博客的其他读者分享.
Also, 如果您想了解Selenium中的自动化测试, 以及如何使用Page Object模型来编写可维护和可重用的测试例程, check out Selenium中的自动化:页面对象模型和页面工厂.
在执行一些代码之前,Sleep总是会暂停一段时间, 而wait只会暂停执行,直到出现预期的条件或超时, 先到者为准. 您不应该在测试自动化框架中使用sleep,因为您希望测试尽可能快地运行.
这是当您使用Java编程语言创建自动化测试时.
为了编写在浏览器中运行功能测试的web应用程序的自动化测试用例, 您必须使用像Selenium库这样的工具, 正如我们在本文中所做的那样. 您还需要使用测试框架,如TestNG或JUnit.
您可以使用许多测试和断言框架来运行selenium驱动的自动化测试. 我使用TestNG是因为它是专门为验收测试设计的, 而像JUnit这样的框架通常用于单元测试. 另一个值得研究的伟大框架是Spock,因为它具有很强的表现力并且易于阅读. Google的Truth断言库也是编写可读测试的好方法.
西蒙已经做了18年的技术测试员. 他从IBM开始,转到EADS,然后是富士通,现在经营着自己的公司.
世界级的文章,每周发一次.
世界级的文章,每周发一次.