【问题标题】:Selenium and TestNG Using Both 'dependsOn' and 'priority =' IssueSelenium 和 TestNG 同时使用“dependsOn”和“priority =”问题
【发布时间】:2013-09-07 15:43:24
【问题描述】:

我正在努力在我的 GUI 自动化测试中实现更好的工作流控制。我一开始是用dependsOn,但很快发现缺点是如果一个测试失败,整个套件的其余部分都不会运行。所以我改用'priority=',但看到了意外的行为。一个例子:

@Test(priority = 10)
public void login(){...}

@Test(priority = 20, dependsOnMethods = "login")
public void verifyUserLogin() {...}

@Test(priority = 30, dependsOnMethods = "verifyUserLogin")
public void navigateToReportSettings() {...}

@Test(priority = 40, dependsOnMethods = "navigateToReportSettings")
public void verifyGeneralSettings() {...}

@Test(priority = 40, dependsOnMethods = "navigateToReportSettings")
public void verifyReportingPeriod() {...}
...
@Test(priority = 90, dependsOnMethods = "navigateToReportSettings")
public void saveReportSettings() {...}

我想要发生的事情:

  1. 登录。
  2. 验证用户是否已登录。
  3. 导航至报告设置页面。
  4. 验证报告设置页面上的常规设置和报告周期(以任意顺序)
  5. 进行一些更改并保存。
  6. 重要提示:10、20 和 30 必须成功或跳过其余部分。如果任何 40 个失败,则在所有 40 个都完成后继续到 50 个。但不依赖任何步骤 40 才能成功!

发生了什么:

  1. 登录(优先级 10)。
  2. 保存(优先级 90)。

注意:还有“组”注释,但我认为这与此处无关。 提前感谢您提供有关如何成功组合优先级和dependsOn 以控制工作流的任何提示,但仅在需要时使用依赖项。

这是另一个示例代码。 我不知道为什么它按这个顺序运行: 输出: 10, 20, 30, 40 等... 110, //OK 130, 140, 150, 160, // 为什么跳过了 120 个优先级? 120, 120, 120, etc... 120 //最后运行? 同样有趣的是,120 组可以按顺序重新编号(121、122、123 等),但它们仍然排在最后。

因此,问题一定是“dependsOn”和“priority =”不能很好地配合使用。我很好奇是否有人让这两个在他们的环境中工作。谁知道它可能是 Intellij IDEA?无论如何,我需要尽快了解这一点,以避免以后进行昂贵的重构!再次感谢您的任何反馈-JR

@Test(priority = 10, groups = "A")
public void login(){

System.out.println("10");

}


@Test(priority = 20, groups = {"A", "B"})
public void openUserAdministrationTest() {

    System.out.println("20");

}

@Test(priority = 30, groups = {"A", "B"})
public void usersTabTest() {

    System.out.println("30");

}

@Test(priority = 40, groups = {"A", "B"})
public void createUserTabTest() {

    System.out.println("40");

}


@Test(priority = 50, groups = {"A", "B"})
public void userCreationDataEntryTest() {

    System.out.println("50");

}

@Test(priority = 60, groups = {"A", "B", "C"})
public void userRolesTest() {

    System.out.println("60");

}

@Test(priority = 70, groups = {"A", "B"})
public void saveUserTest() {

    System.out.println("70");

}

@Test(priority = 80, groups = {"A", "B"})
public void closeUserAdminAndLogoutTest() {

    System.out.println("80");

}

@Test(priority = 90, groups = "A")
public void loginNavigateToUserAdmin() {

    System.out.println("90");
}

@Test(priority = 100, groups = {"A", "D"})
public void verifyUserSearchUserReturned() {

    System.out.println("100");

}

@Test(priority = 110, groups = {"A", "D"})
public void reOpenNewUserTest() {

    System.out.println("110");

}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserUserNameTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserFullNameTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserDepartmentTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserPhoneNumberTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserEmailTest() {

    System.out.println("120");
}

//      Note: password and active verified by user login

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserActiveCheckedTest() {
    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserLanguageTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserDateFormatTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserNumberFormatTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserReportingPeriodTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserReportingPeriodExampleTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserReferencePeriodTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserReferencePeriodExampleTest() {

    System.out.println("120");
}

@Test(priority = 120, groups = {"A", "E"}, dependsOnMethods = "reOpenNewUserTest")
public void verifyNewUserShowAnnotationsCheckedTest() {
    System.out.println("120");
}

@Test(priority = 130, groups = {"A", "C"})
public void verifyNewUserRoleTest() {

    System.out.println("130");
}


@Test(priority = 140, groups = {"A", "C"})
public void verifyNewUserFunctionalRoleTest() {

    System.out.println("140");

}

@Test(priority = 150, groups = {"A", "C"})
public void verifyUserAdminCloseAndLogoutTest() {

    System.out.println("150");

}

@Test(priority = 160, groups = {"A", "C"})
public void verifyUserLogin() {

    System.out.println("160");

}

这是一个简单得多的例子,但也展示了如何简单地打破优先级:

@Test(priority = 10)
public void test10(){
    System.out.println("10");
}

@Test(priority = 20, dependsOnMethods = "test10")
public void test20() {
    System.out.println("20, depends on 10");
}

@Test(priority = 30, dependsOnMethods = "test20")
public void test30() {
    System.out.println("30, depends on 20");
}

@Test(priority = 40, dependsOnMethods = "test10")
public void test40() {
    System.out.println("40, depends on 10");
}

应该运行:10、20、30、40。 运行次数:10、20、40、30。

【问题讨论】:

  • 一个测试不应该依赖于另一个测试。这会在您的测试框架中引入依赖关系。依赖=很多麻烦,没有太多收获,很多领域都失败了。我的建议:结合测试。
  • 是的,这个论点我听过很多次了……但是在很多情况下,依赖关系和工作流应该被控制。例如,您创建用户、以管理员身份注销、以新用户身份登录、创建报告并验证用户权限的场景。这可能是一个测试用例,但实际上应该是 10 或 15。您不希望整个测试失败,因为在创建用户步骤中说电话号码字段存在问题。一个失败的断言将使整个测试用例失败。因此需要工作流和依赖关系。它还可以最大限度地减少重复代码...
  • @JackRyan 如果需要考虑将许多测试组合成一个“@Test”,其中有太多断言,那么请考虑使用soft assertions。然后,将执行所有代码(读取断言),然后将发生最终失败。只是对一个小问题的建议。
  • @Arran 将所有测试保存在单个 @Test 中会很糟糕的原因是 Jack Ryan 提到的一个原因,另一个是根据不同场景的测试可重用性。尤其是在自动化 UI 测试中,这都是关于不同场景的。在两种不同的情况下,将会有一些总是常见的测试。那么为什么要将这些测试的代码作为不同的测试重复呢?
  • @JackRyan 我执行了您提供的代码,它按预期工作。你错过了什么吗??

标签: java selenium selenium-webdriver testng


【解决方案1】:

要使测试即使在失败后也能运行,请使用 alwaysRun 属性和 dependsOnMethods 而不是使用 priority 属性 alwaysRun 属性让下一个依赖在失败后也能执行,试试下面的语法:

@Test
public void login(){...}

@Test(dependsOnMethods = "login")
public void verifyUserLogin() {...}

@Test(dependsOnMethods = "verifyUserLogin")
public void navigateToReportSettings() {...}

@Test(dependsOnMethods = "navigateToReportSettings", alwaysRun=true)
public void verifyGeneralSettings() {...}

@Test(dependsOnMethods = "navigateToReportSettings", alwaysRun=true)
public void verifyReportingPeriod() {...}
...
@Test(dependsOnMethods = "navigateToReportSettings")
public void saveReportSettings() {...}

【讨论】:

  • 值得注意的是,在这种情况下verifyGeneralSettingsverifyReportingPeriod 将始终运行,即使verifyUserLogin 失败。如果只有 一些 依赖项失败,似乎没有办法“始终运行”。
【解决方案2】:

不提供优先级和依赖在一起,可以将测试分组。你可以这样做 例如,

@Test(priority = 10, groups = { "10" })
public void test10() {
    System.out.println("10");
}

@Test(dependsOnMethods = "test10", groups = { "10" })
public void test20() {
    System.out.println("20, depends on 10");
}

@Test(dependsOnGroups = { "10" })
public void test30() {
    System.out.println("30, depends on 20");
}

@Test(dependsOnMethods = "test30")
public void test40() {
    System.out.println("40, depends on 10");
}

必须运行的第二件事(成功或跳过其余部分)

您将始终按照您所依赖的方法运行,即使其中一些方法失败了。当您只想确保您的测试方法以特定顺序运行但它们的成功并不真正取决于其他人的成功时,这很有用。通过在 @Test 注释中添加“alwaysRun=true”来获得软依赖。

如果依赖的方法失败并且您对它有硬依赖(alwaysRun=false,这是默认设置),则依赖它的方法不会标记为 FAIL,而是标记为 SKIP。跳过的方法将在最终报告中报告(在 HTML 中以既不是红色也不是绿色的颜色),这很重要,因为跳过的方法不一定是失败的。

【讨论】:

    【解决方案3】:

    有很多与dependsOnMethods注解相关的缺陷。我在 6.5.2 中遇到过类似的情况。尝试将您的依赖项更新到 6.8.3。

    【讨论】:

    • 是的,我愿意。 TestNG 6.8.3 是最新的稳定版本。 (6.8.5有些问题)
    • 我没有找到 TestNG 6.8.3 的预构建 jar 版本,但只有 github 版本上的源代码。必须自己建造吗??
    • 请再检查一次。 maven repos中有一个6.8.3
    • 顺便说一句,我已经测试了 6.8.2、6.8.3、6.8.5,最新版本:6.8.7。在所有版本中,依赖关系都会破坏优先级。
    猜你喜欢
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多