ruby - 页面对象模型 : why not include assertions in page methods?

标签 ruby selenium webdriver selenium-webdriver pageobjects

第一张海报。我从事 UI 自动化工作多年,但直到最近才被介绍/受命使用页面对象模型。其中大部分是常识,包括我已经使用过的技术,但有一个特别好的地方我无法在自己的脑海中证明,尽管广泛搜索了合理的解释。我希望这里有人能启发我,因为这个问题在我尝试将 POM 与我自己的最佳实践集成时引起了一些惊愕。

来自 http://code.google.com/p/selenium/wiki/PageObjects :

The code presented above shows an important point: the tests, not the PageObjects, should be responsible for making assertions about the state of a page.... Of course, as with every guideline there are exceptions...

来自 http://seleniumhq.org/docs/06_test_design_considerations.html#chapter06-reference :

There is a lot of flexibility in how the page objects may be designed, but there are a few basic rules for getting the desired maintainability of your test code. Page objects themselves should never be make verifications or assertions. This is part of your test and should always be within the test’s code, never in an page object. The page object will contain the representation of the page, and the services the page provides via methods but no code related to what is being tested should be within the page object.

There is one, single, verification which can, and should, be within the page object and that is to verify that the page, and possibly critical elements on the page, were loaded correctly. This verification should be done while instantiating the page object.

这两个“准则”都允许潜在的异常(exception)情况,但我非常不同意基本前提。我习惯于在“页面方法”中做大量的验证,我认为验证的存在是一种强大的技术,可以在各种上下文中发现问题(即每次调用方法时都会进行验证)而不是而不是只发生在特定测试的有限上下文中。

例如,假设当您登录 AUT 时,会出现一些文本,上面写着“以用户身份登录”。有一个单独的测试专门验证这一点是合适的,但是您为什么不想每次调用登录时都验证它呢?这个工件与页面是否“正确加载”没有直接关系,并且通常与“正在测试的内容”无关,所以根据上面的 POM 指南,它显然不应该在页面方法中。 .. 但在我看来,它显然应该存在,通过尽可能频繁地验证重要工件来最大化自动化的力量,尽可能少地预先考虑。将验证代码放在页面方法中,可以让您“免费”获得大量验证,而无需在测试中担心,这种在不同上下文中进行的频繁验证通常会发现您不会发现的问题如果验证仅限于,比如说,对该工件的单个测试。

换句话说,我倾向于区分特定于测试的验证和“一般”验证,并且我认为将后者广泛地包含在页面方法中是完全合适/可取的。这促进了更薄的测试和更厚的页面对象,这通常通过重用更多代码来增加测试可维护性——尽管这些指南中有相反的争论。我错过了重点吗?不想在页面方法中进行验证的真正理由是什么?我描述的情况实际上是这些指南中描述的“异常(exception)”之一,因此实际上与 POM 不一致吗?提前感谢您的想法。 -jn-

最佳答案

作为准则,断言应该在测试中而不是在页面对象中完成。当然,有时这不是一种实用的方法,但这种情况很少见,以至于上述准则是正确的。以下是我不喜欢在页面对象中使用断言的原因:

  1. 阅读一个只调用 verify 方法的测试是非常令人沮丧的,其中断言被埋在页面对象的其他地方。在可能的情况下,测试断言的内容应该是显而易见的;当断言直接在测试中时,这是最好的实现方式。通过将断言隐藏在测试之外的某处,测试的意图就不那么清楚了。

  2. 浏览器测试中的断言可能代价高昂 - 它们确实会减慢您的测试速度。当您有数百或数千个测试时,可以将分钟/小时添加到您的测试执行时间中;这是一件坏事。如果将断言移至只关注那些特定断言的测试,您会发现测试速度会快得多,并且仍然会发现相关缺陷。问题包括以下内容:

    Putting verification code in page methods multiplies the power of automation by allow you to get a lot of verification "for free"

    好吧,“自由不是免费的”:)您实际上增加的是您的测试执行时间。

  3. 到处都有断言违反了另一条很好的准则; “每个测试一个断言”(http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html)。我并不虔诚地坚持它,但我尽量遵循这个原则。在可能的情况下,测试应该只对一件事感兴趣。

  4. 测试的值(value)降低了,因为一个错误会导致大量测试失败,从而阻止他们测试他们应该测试的东西。

    For example, let's imagine that when you login to your AUT, some text appears that says "logged in as USER". It's appropriate to have a single test validate this specifically, but why wouldn't you want to verify it every time login is called?

    如果您在页面对象类中有断言并且预期的文本发生更改,则所有 登录测试都将失败。相反,如果断言在测试中,那么只有一个测试会失败——专门测试正确消息的测试——让所有其他测试继续运行以查找其他错误。您不需要 5,000 次测试来告诉您登录消息是错误的; 1 个测试即可;)

  5. 让一个类(class)做不止一件事违反了 SOLID 中的“S” , 即: ' Single Responsibility Principle '(建议零售价)。一个类应该负责一件事,而且只负责一件事。在这种情况下,页面对象类应该负责对页面(或其部分)进行建模,仅此而已。如果它做的不止于此(例如:包括断言),那么您就违反了 SRP。

关于ruby - 页面对象模型 : why not include assertions in page methods?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11126806/

相关文章:

Ruby Sinatra 在没有 PEM 和 OpenSSL::SSL::VERIFY_NONE 的情况下创建发布请求

ruby-on-rails - 如何从 Rails 应用程序管理长时间运行的进程?

java - Selenium RC Java - isElementPresent 不起作用

python - 简单的网页更改或按钮删除和抓取的数据是无用的

ruby-on-rails - Rails 5 - 在编辑操作中使用范围来查找特定实例的相关子项

ruby - 在开发模式下,Rails 应用程序的 Docker 容器运行速度非常慢

Python Selenium 查找元素 XPath 不起作用

python - 手动创建新的 webdriver session

java - 如何将枚举与命令行参数一起使用?

php - 在 webdriver 中呈现 HTML 字符串或本地 html 文件