我想知道用于自动化大规模 SaaS 产品的 Selenium 的最佳设计模式。
寻找您对此的所有评论。
对于大型应用程序,我更喜欢将我的 xpath 用于页面对象文件中的 web 元素。但我的领导希望我将 xpath 保留在属性文件中,我们应该访问每个 xpath 的属性文件。这是将 xpath 保存在大型 SaaS 应用程序的属性文件中的好方法吗?
我想知道用于自动化大规模 SaaS 产品的 Selenium 的最佳设计模式。
寻找您对此的所有评论。
对于大型应用程序,我更喜欢将我的 xpath 用于页面对象文件中的 web 元素。但我的领导希望我将 xpath 保留在属性文件中,我们应该访问每个 xpath 的属性文件。这是将 xpath 保存在大型 SaaS 应用程序的属性文件中的好方法吗?
您的 leed 希望您实施Object Repository Pattern。
我认为这个想法与广泛使用的 HP QTP(QuickTest Professional)一样古老 - 但我可能错了,这只是我的意见。
简而言之(来自上述链接的引用):
对象存储库是我们可以存储对象信息的集中位置,它充当测试脚本和应用程序之间的接口,以便在执行期间识别对象。
我们始终建议使用外部文件作为对象存储库,而不是将对象及其属性直接硬编码到我们的代码中。如果你问我这是为什么?原因是因为它减少了维护工作并提供了积极的投资回报率,例如,假设我们正在测试的应用程序中的任何对象属性发生变化,我们可以轻松地在外部对象存储库文件中更改它,而不是单独搜索和更新该对象编码
想象一个场景,你有一个网页,它有多个部分、多个框架和数百个 WebElement。显然,一旦您键入页面名称,您就不希望这样做,它会为您提供网页上可用的所有元素。如果元素很少,可以使用相同的结构,但如果元素很多,则建议将页面分成不同的部分,例如页眉、页脚、左侧导航、中心内容和右侧导航。然后将每个 WebElement 分类到其父元素下。
我认为这种模式与页面对象模式并不矛盾,它们可以很好地协同工作。它为项目带来了更大的透明度,并迫使开发人员/测试人员保持项目更好的可读性,这有助于在未来维护它。
但以上只是一点理论,有人可能会问这种模式在现实生活中有何帮助?
考虑一个简单的例子。假设有一段代码:
public class SomePageObject{
.....
.....
public void doSomething(String value){
findElement( By.xpath("//*[ @class='left-content']//button[ contains( ., 'list-selector' )]") ).click();
wait.until( ExpectedConditions.visibilityOfElementLocated( By.xpath( String.format( "//li[ *[ text() = '%s' ]]", value ))).click();
}
我已经看过这样的代码数百次了。你觉得这段代码怎么样?
是的,它遵循众所周知的页面对象模式。但这太可怕了。
看看这段代码,你能猜出它在做什么吗?绝对
不会。当此代码由于第二个元素的 UI 更改而中断时,您会在日志中收到什么错误消息?最有可能是这样的:
org.openqa.selenium.TimeoutException: Timed out after 30 seconds
waiting for visibility of element located by By.selector: //li[ *[ text() = 'New York' ]]
仅查看此错误消息,您能猜出它涉及应用程序的哪一部分以及在代码中的哪个位置可以找到它? 不会。
自动化工程师可以在查看堆栈跟踪的代码中找到它,但不了解 java、selenium 等的初级测试人员无法仅查看错误和打印屏幕(如果可用)来修复它。
在许多情况下,为了修复错误,自动化工程师需要在本地机器上运行这个测试用例来复制问题。
使用对象存储库模式看起来如何?
可能有一个可能如下所示的属性文件:
....
orderPage.citySelectButton=//*[ @class='left-content']//button[ contains( ., 'list-selector' )]
orderPage.citySelectListElement=//li[ *[ text() = '%s' ]]
...
...
和一个看起来像这样的代码:
public class SomePageObject{
.....
.....
public void doSomething(String value){
objRepoFacade( "orderPage.citySelectButton" ).click();
objRepoFacade( "orderPage.citySelectListElement", value ).wait().click();
...
)
}
日志中的错误消息可能如下所示:
RuntimeException: time out waiting for element: orderPage.citySelectListElement
located by By.selector: //li[ *[ text() = 'New York' ]]
现在,即使是初级测试人员,只看这个错误消息,也能够很容易地猜出错误发生在应用程序的哪个部分,以及哪个元素被破坏了。测试人员可能会接受培训,如何使用开发人员控制台 (F12) 检查页面上的元素,更正 procerties 文件中的选择器,并在没有自动化工程师帮助且完全不接触代码的情况下自行解决问题。
大概从您的 leed 的角度来看,后者(对象存储库)是一个更好的解决方案,因为它可以雇用更多的初级测试人员和更少的自动化工程师并降低成本。