gpt4 book ai didi

java - Selenium + JUnit : test order/flow?

转载 作者:行者123 更新时间:2023-11-28 19:41:46 25 4
gpt4 key购买 nike

我正在使用 Selenium 来测试我的 Java Web 应用程序的 html 页面(实际上是 JSP)。我的网络应用程序需要一个流程来访问每个页面(它是一个小型在线游戏网络应用程序),例如:要转到页面 B,您需要转到页面 A,输入一些文本并按一个按钮进入页面B. 显然我已经进行了一些测试来验证页面 A 是否正常工作。

我希望能够编写更多测试,以检查在 A 页面的测试运行后我是否会运行 B 页面的测试(对于应用程序的其余部分,依此类推)。简而言之:以某种方式在我的测试中定义一些顺序。

在过去几天阅读了大量有关测试的文章后,我找不到关于这个特定主题的任何有趣内容。因此,我现在寻求建议。

我已经确定的可能解决方案:

  • 为页面 A 定义(在同一测试类中)测试方法,然后为测试 B 定义测试方法。然后对测试方法的执行进行排序。但是我们知道 JUnit(但 TestNG 允许)不允许测试方法执行顺序,参见 SO question selenium-junit-tests-how-do-i-run-tests-within-a-test-in-sequential-order
  • 将所有测试(对于页面 A、页面 B 等)分组到一种测试方法下。但我读过它很糟糕,见 SO question: junit-one-test-case-per-method-or-multiple-test-cases-per-method .做 Selenium 测试有那么糟糕吗?我见过一些代码这样做,所以我认为它可能不是。
  • 将所有测试(对于页面 A、页面 B 等)分组到一种测试方法下,但使用 JUnit 的 ErrorCollector 类:ErrorCollector允许您以相同的方法执行有序检查,并在失败时产生特定的错误消息,但让方法(因此检查)运行直到结束。这个解决方案对我来说似乎太“残酷”了。
  • 使用 JUnit 的 TestSuite 类:它按照套件中定义的测试类的顺序运行套件中列出的测试。因此,这将涉及使用独立的测试方法来测试测试类(假设为 TestA)中的页面 A,然后使用所有测试方法来测试测试类(假设为 TestB)中的页面 B,依此类推。然后将它们插入到测试套件中,例如 @SuiteClasses( {TestA.class, TestB.class, TestC.class, ...} )
  • 使用 JUnit's TestSuite class结合 JUnit 的 ErrorCollector 类。哦,既然我们可以,您可能希望在不同的类中对每个页面进行分组测试,并在该组页面之上使用 ErrorCollector 测试“区域”。如果您有一个非常密集的网页或其他原因,此解决方案可能非常有用。
  • 相当激进:使用其他工具,例如 TestNG可以访问诸如测试方法排序之类的功能。

  • 注意:我想有些人会推荐最后一个解决方案(迁移到 TestNG),但我也想听听其他与 JUnit 相关的想法/意见。比如,如果我在一个无法(出于某种原因)迁移到另一个测试框架的团队中工作,那么他们将如何解决这个测试排序问题?

    最佳答案

    为什么要迁移?您可以使用 JUnit 进行单元测试,使用另一个框架进行更高级别的测试。在您的情况下,它是一种接受或功能或端到端,您如何命名它并不重要。但重要的是要了解这些测试不是单元。它们遵循不同的规则:它们更复杂、运行时间更长且频率更低、它们需要复杂的设置、外部依赖,并且可能偶尔会失败。为什么不为它们使用另一种框架(甚至另一种编程语言)?

    可能的变体是:

  • BDD 框架:已经提到 Cucumber , JDave , JBehave , Spock .例如,Spock 基于 JUnit 和 Groovy =)
  • TestNG

  • 如果添加另一个框架不是一个选项:您为 JUnit 枚举了更多选项,那么我可以想象 =) 我会将流程的整个测试脚本放在一个测试方法中,并将测试代码组织到“驱动程序”中。这意味着您的端到端测试不会直接调用您的应用程序或 Selenium API 的方法,而是将它们包装到 Driver 组件的方法中,这些方法隐藏了 API 的复杂性,看起来像是发生了什么或预期什么的语句。看例子:
    @Test 
    public void sniperWinsAnAuctionByBiddingHigher() throws Exception {
    auction.startSellingItem();

    application.startBiddingIn(auction);
    auction.hasReceivedJoinRequestFrom(ApplicationRunner.SNIPER_XMPP_ID);

    auction.reportPrice(1000, 98, "other bidder");
    application.hasShownSniperIsBidding(auction, 1000, 1098);

    auction.hasReceivedBid(1098, ApplicationRunner.SNIPER_XMPP_ID);

    auction.reportPrice(1098, 97, ApplicationRunner.SNIPER_XMPP_ID);
    application.hasShownSniperIsWinning(auction, 1098);

    auction.announceClosed();
    application.hasShownSniperHasWonAuction(auction, 1098);
    }

    一个片段取自“ Growing Object-Oriented Software Guided by Tests”。这本书真的很棒,我强烈推荐阅读。

    这是真正的端到端测试,使用真正的 XMPP 连接、Openfire jabber 服务器和 WindowLicker Swing GUI 测试框架。但是如果将所有这些东西卸载到驱动程序组件。在您的测试中,您只会看到不同的参与者如何交流。它是有序的:在应用程序开始出价后,我们检查拍卖服务器是否收到加入请求,然后我们指示拍卖服务器报告新价格并检查它是否反射(reflect)在 UI 等中。完整代码可在 github 上获得.

    github 上的例子很复杂,因为应用程序并不像书上的例子那样琐碎。但是那本书逐渐给出了它,我能够按照本书指南从头开始构建整个应用程序。事实上,这是我读过的关于 TDD 和自动化开发人员测试的唯一一本书,它给出了如此全面和完整的示例。我读了很多。但请注意,驱动程序方法不会使您的测试成为单元。它只是让你隐藏复杂性。它也可以(并且应该)与其他框架一起使用。如果需要,它们只是为您提供了将测试拆分为连续步骤的更多可能性;编写用户可读的测试用例;将测试数据外部化为 CSV、Excel 表格、XML 文件或数据库,使您的测试超时;与外部系统、servlet 和 DI 容器集成;分别定义和运行测试组;以提供更人性化的报告等。

    以及关于制作所有测试单元。除了用于数学、字符串处理等的实用程序库之外,任何东西都是不可能的。如果您的应用程序完全经过单元测试,则意味着您不是测试所有应用程序,或者您不了解哪些测试是单元测试,哪些不是。第一种情况可能没问题,但未涵盖的所有内容都必须由开发人员、测试人员、用户或任何人手动测试和重新测试。这是很常见的,但最好是有意识的决定而不是随意的决定。为什么你不能单元测试一切?

    单元测试有很多定义,它会导致圣战)我更喜欢以下内容:“单元测试是对程序单元进行隔离测试”。有人说:“嘿,单元是我的应用程序!我测试登录,它是简单的单元功能”。但也有孤立隐藏的语用学。为什么我们需要与其他单元测试不同?因为这是我们的第一个安全网。他们必须很快。您经常提交(例如到 git),并且至少在每次提交之前运行它们。但是想象一下,“单元”测试需要 5 分钟才能运行。您要么减少运行它们的频率,要么减少提交的频率,要么一次只运行一个测试用例甚至一种测试方法,要么每隔 2 分钟等待一次,以便测试在 5 分钟内完成。在那 5 分钟内,您将进入 Coding Horror,在那里您将花费接下来的 2 小时 =) 并且单元测试绝不能偶尔失败。如果他们这样做 - 你不会相信他们。因此,隔离:您必须从单元测试中隔离缓慢和零星故障的来源。因此,隔离意味着单元测试不应该使用:
  • 文件系统
  • 网络、套接字、RMI 等
  • 界面
  • 多线程
  • 外部库需要测试框架并支持像 Hamcrest 这样的简单库

  • 并且单元测试必须是本地的。当您在编码后 2 分钟内出现缺陷时,您希望只有一个左右的测试失败,而不是整个套件的一半。这意味着您在单元测试中测试有状态行为的能力非常有限。您不应该进行 5 次状态转换以达到前提条件的测试设置。因为第一次转换失败将中断至少 4 个针对后续转换的测试,以及您当前为第 6 个转换编写的另一个测试。任何非平凡的应用程序都有相当多的流和状态转换。所以这不能进行单元测试。出于同样的原因,单元测试不得在数据库、静态字段、Spring 上下文或其他任何内容中使用可更改的共享状态。这正是 JUnit 为每个测试方法创建新的测试类实例的原因。

    因此,您看,无论您如何重新编码,都无法对 Web 应用程序进行完整的单元测试。因为它有流、JSP、servlet 容器等等。当然,您可以忽略此定义,但它非常有用)如果您同意将单元测试与其他测试区分开来是有用的,并且此定义有助于实现这一点,那么您将使用另一个框架或至少另一种方法不是单元的测试,您将为不同类型的测试创建单独的套件等等。

    希望,这会有所帮助)

    关于java - Selenium + JUnit : test order/flow?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12404430/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com