引言
在今年年初,我在公司使用Selenium编写客户端测试。对于那些主要使用Scala编写的开发人员来说,这是很好的事。问题在于学习Scala和Selenium是开发人员编写端到端测试的高标准。我们有很多开发人员几乎都是用TypeScript编写的。作为Scala的新手,对新功能进行客户端测试非常困难,以至于通常不会编写测试。
当我发现Puppeteer时,它似乎是解决这个问题的正确工具。开发人员可以用TypeScript编写测试,这是他们更熟悉的语言。我们已经使用Jasmine编写单元测试,因此使用Jasmine创建Puppeteer测试的能力是一个明显的胜利。Devs还可以在运行测试时连接Chrome DevTools,这样他们就可以使用他们熟悉的调试器。所有这些功能看起来都非常适合降低编写客户端测试的条件。Puppeteer也比Selenium有一些优势。
目录:
更简单的JavaScript执行
网络拦截
测试处理失败的请求
模拟第三方服务
测试离线模式
调试
单个浏览器,单一语言
所以你应该选择selenium而不是Puppeteer吗?
1)、更简单的JavaScript执行
Selenium和Puppeteer的一个强大功能是能够在浏览器中运行JavaScript。这个功能的使用几乎是无穷无尽的,在Puppeteer中使用这个功能几乎是毫不费力的 比较下面这两段代码: Scala + Selenium
val evalResult = Json.parse(driver.executeAsyncScript(“””
var callback = arguments[arguments.length - 1];
asyncFunction().then(callback);
“””).asInstanceOf[String])
TypeScript + Puppeteer
const evalResult = await page.evaluate(() => asyncFunction());
TypeScript版本可以更简单,并具有一些额外的优势。首先,TypeScript版本自动处理异常。如果AslenFunction在Selenium版本中失败,则不会出现错误; 相反,它会超时。您可以,也可能应该创建一个包装函数,以简化调用JavaScript并正确处理错误,如果您使用Selenium。但是,由于基础实现已经更简单,Puppeteer在这里是更好的选择。无需修改界面。
Puppeteer版本还具有TypeScript检查类型的优势。您可以声明evaluate内部使用的函数和变量,如果您有语法或类型错误,TypeScript将捕获这些错误。在Selenium中,在尝试运行测试之前,您不会捕获错误。
这些优势的核心归结为让测试驱动程序使用与浏览器相同的语言。这使得连接两者更加无缝。作为一个注释,您可以在TypeScript中编写Selenium测试并实现类似的无缝evaluate实现,但这不是我们的Scala代码的选项 - 这就是为什么我将此列为我想切换到Puppeteer的原因。
2)、网络拦截
这是Puppeteer对Selenium的最强大优势。您的测试代码可以记录,修改,阻止或生成浏览器发出的请求的响应。乍一看,这似乎不是一个非常有用的功能,但它有助于解决许多难以解决的问题。
3)、测试处理失败的请求
通过让Puppeteer有选择地使某些请求失败,您可以验证您的产品在这些情况下是否正常失败。您可以使用此过程在上载失败时验证错误消息是否正确。如果图像未加载,您可以验证页面布局是否会崩溃。
4)、模拟第三方服务
我有使用此类别中的网络拦截的第一手经验。我们想为Salesforce块编写一些自动化测试。问题在哪呢?我们的Salesforce插件依赖于调用Salesforce API。如果我们编写测试来登录现有的Salesforce帐户来运行这些测试,我们会遇到一些问题:我们必须依赖与Salesforce建立可靠连接的测试机器,Salesforce GUI中的更改将导致我们的测试突然失败并且没有任何错误,Salesforce可以检测到我们正在以机器人身份登录并安装CAPTCHA或需要两步验证。让人惊讶。Puppeteer为我们解决了这个问题。我们能够编写一个在本地运行的模拟Salesforce API。任何对Salesforce的请求都会被Puppeteer截获,并且伪造的数据会在其位置返回。
5)、测试离线模式
Puppeteer也可以模拟离线。您可以编写测试以确保您的产品正确处理失去Internet连接的问题。这种能力对于为我们最近添加到产品中的离线模式功能编写单元测试至关重要。我们能够创建单元测试以验证更改是否已脱机保存,并且当连接返回时,更改将保存到服务器。如果没有这个功能,我们将完全依赖于单元测试或试图以最不能测试我们的离线功能的方式伪造离线模式。
6)、调试
由于Puppeteer可以收到来自浏览器的所有请求和响应的通知,因此您也可以简单地记录该信息 - 这在尝试诊断构建服务器上运行的测试失败的问题时非常有用。作为构建系统的一部分,当我们的一个Puppeteer测试失败时,我们会获得失败时打开的所有选项卡的屏幕截图,以及完整的控制台日志转储以及浏览器发出的所有请求。此信息有助于从构建报告中诊断测试失败,而无需在本地运行它们。当测试仅在我们的构建服务器上失败时,它也是非常有价值的,在那里您没有看到测试运行并且只获得测试结果。
7)、单个浏览器,单一语言
这听起来像是一个缺点。如果我正在写一篇关于为什么Selenium比Puppeteer更好的文章,我肯定会写到一点就是Selenium可以为你提供更多关于你想要使用什么语言的选项,同时更重要的是,Selenium可以让你在多个浏览器上运行你的测试。那么为什么Puppeteer缺少这些功能我还要给它加分呢?因为这些功能需要付费。
在Selenium上搜索代码示例时,您经常会找到另一种语言的示例。您可以在线搜索并找到关于如何使用Selenium的优秀教程或一个显示您想要完成的内容的优秀代码片段,但它们可能使用您不使用且不熟悉的语言。
此外,Selenium给出的“一次编写,在任何浏览器上运行”的承诺在现实世界中并不总是如此。出于某种原因,一些测试将在一个浏览器中传递而在另一个浏览器中没有明确的原因。不同浏览器驱动程序中的错误可能会阻止测试在所有浏览器上可靠运行。如果您愿意投入额外的工作,可以在多个浏览器上运行测试,但只需要针对单个浏览器,这可以大大简化您的开发负载。
8)、所以你应该选择selenium而不是Puppeteer吗?
对于我的情况,我认为选择Puppeteer而不是Selenium是正确的。我并不是说每个人都应该舍弃Selenium。我们仍然为那些喜欢它们的人编写和维护Selenium测试。我也不建议每个人都选择Puppeteer而不选择Selenium。我之所以选择Puppeteer是因为它提供了更简单的Javascript执行,网络拦截以及更简单,更集中的库。我希望这些要点非常有用,这样如果您希望进行客户端测试,就可以做出明智的选择。