一个Selenium项目的单元测试

4
一个关于最佳实践或者说是否需要实践的问题 ;)
我目前正在使用Java中的Selenium工具编写测试自动化系统。该系统旨在用于对Web应用进行端到端的验收测试。测试用例是用Gherkin语言编写的,并由BDD框架Cucumber(Cucumber-JVM)执行。底层函数使用Selenium/WebDriver与AUT和浏览器进行交互。Selenium代码使用PageObject模式进行结构化,这种模式抽象了WebDriver的使用方式。cucumber步骤定义仅调用PageObjects提供的方法。
随着项目的继续,变得越来越复杂,我希望开始编写单元测试,以确保验收测试及其周围的实用程序函数按预期执行 :)
现在来到问题:
为测试自动化项目编写单元测试是否可行?
主要问题是,在我第一次尝试使用TestNG进行单元测试时,我意识到我的单元测试最终做了与验收测试相同或类似的事情。这是低效的,因为单元测试非常慢且有很多依赖项。
那么在这种情况下,是否只测试实用程序类并让Selenium代码保持不变呢?即仅测试可以在不调用Selenium WebDriver并与AUT进行交互的情况下测试的内容?
注意:只是为了确保没有被误解。我询问的是在验收测试代码和所有辅助代码上运行单元测试,而不是使用像JUnit或TestNG这样的单元测试框架运行Selenium测试用例。
如果编写测试用于测试是否合理,任何帮助和/或想法将不胜感激;)

感谢Kiril和Thomas提供的有见地的答案。在进一步探索后,我已经为所有不访问Selenium的实用类实现了单元测试。 我部分同意Thomas所写的,认为这应该足够了。但就个人而言,我会更安心,如果至少有一小部分测试来测试使用Selenium进行低级浏览器交互的方法。如果时间允许,我将尝试实现这些测试。 - namarath
2个回答

10

我相信有些人可能会认为我的回答“带有个人见解”并因此投票反对,但无论如何,我认为

是的,如果你依赖于一个测试框架进行验收测试,那么该框架本身也需要测试。

根据我的经验,价值在于以下两个方面:

  1. 可以自信地更改框架。当创建某个函数时,你对它了解得很多,即它支持哪些用例、设计目的等等。但其他人(甚至是你一年后)可能没有同样的了解,即使有文档。因此,要么每次有人需要对行为进行轻微修改(因为他们不自信更改现有函数),就会出现新的函数,要么有人可能会破坏整个验收测试集。

    最好的情况是这些测试是真正的单元测试,能够完全独立于任何东西运行(使用模拟对象、预定义静态测试数据等)。

  2. 防止Selenium本身意外更改/出现错误(或其他重要的第三方库)。当你更新Selenium到下一个版本时(通常需要每3-6个月进行一次),总有可能他们更改了你所依赖的某些默认设置(你甚至不知道),或者出现了错误,或突然返回不同的异常,或者不在先前抛出异常等等。当然不需要过度复制Selenium自己的单元测试,但是对于非平凡的事情或依赖于一些文档不完善的特性,这些测试可能会有很大帮助。

    这些是集成测试。理想情况下,它们应该针对仅用于测试的Web应用程序(而不是实际应用程序)运行,以便以一种方便测试的方式复制特定测试行为。

当然,也可以做一些妥协。例如,使用少量的验收测试作为单元/集成测试的子集(首先运行它们,只有在它们通过时才运行其他测试)。在调试/修复测试框架问题时,从这些测试开始可能更便宜,并逐渐迁移到正确的单元/集成测试。

另一个问题是,如何将测试框架的测试与产品实际验收测试分开。我采用的方法是将测试框架和验收测试放在两个独立的项目中。这样,如果需要,我就可以更改框架、构建它(这也包括运行单元测试和集成测试)多次。当所有单元测试和集成测试都通过后,我再更新实际验收测试所使用的版本。

0

就我个人而言,我不会编写测试测试代码的测试代码。

编写测试来保护自己免受Selenium等第三方工具中的错误是我不会做的事情。如果测试通过并且验证了预期结果,那对我来说就足够了。

当我升级到新版本的Selenium时,我会在有一个工作状态时进行。也就是说,所有测试都通过了。唯一的变化将是Selenium版本。如果现在有测试停止工作,我知道Selenium在这个版本中的行为与我预期的不同,并可以相应地采取行动。

我会为我可能需要的任何复杂实用功能编写测试。

但是,我会努力编写易于理解的测试代码,并避免其中任何复杂的内容。然后仔细验证每个测试是否验证了我期望的行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接