Java 硒和TestNG同时使用';德彭森';和';优先级=';问题

Java 硒和TestNG同时使用';德彭森';和';优先级=';问题,java,selenium,selenium-webdriver,testng,Java,Selenium,Selenium Webdriver,Testng,我正致力于在GUI自动化测试中实现更好的工作流控制。我首先从dependsOn开始,但很快发现缺点是,如果一个测试失败,整个套件的其余部分都不会运行。所以我改用“priority=”,但我看到了意想不到的行为。一个例子: @Test(priority = 10) public void login(){...} @Test(priority = 20, dependsOnMethods = "login") public void verifyUserLogin() {...} @Test(

我正致力于在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() {...}
我想发生的事:

  • 登录
  • 验证用户是否已登录
  • 导航到“报告设置”页面
  • 验证“报告设置”页面上的常规设置和报告周期(按任意顺序)
  • 进行一些更改并保存
  • 重要提示:10、20和30必须成功或跳过其余部分。如果任何40个都失败,则在所有40个都完成后继续50个。但不依赖于任何步骤40成功 正在发生的事情:

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

    下面是另一个示例代码。 我不知道为什么它会以这种顺序运行: 输出: 10、20、30、40等等。。。110,//好的 130140150160,//为什么跳过120个优先级? 120、120、120等等。。。120//最后一个跑? 同样有趣的是,120组可以按顺序重新编号(121、122、123等),但它们仍然是最后运行的

    因此,问题一定是‘dependsOn’和‘priority=’不能很好地结合在一起。我很好奇是否有人让这两个人在他们的环境中工作。谁知道呢,也许这是一个关于Intellij的想法?无论如何,我需要尽快弄清这一点,以避免以后昂贵的重构!再次感谢您的反馈-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。

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

    不提供优先级,取决于一起,您可以将测试分组。你可以这样做 比如说,

    @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,这是默认值),则依赖它的方法不会标记为失败,而是标记为跳过。跳过的方法将在最终报告中以同样的方式报告(在HTML中以既不是红色也不是绿色的颜色),这一点很重要,因为跳过的方法不一定会失败。

    要使测试在失败后仍能运行,使用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() {...}
    

    一项测试不应依赖于另一项测试。这将在测试框架中引入依赖关系。依赖性=有很多麻烦,没有多少收获,有很多地方需要放弃。我的建议是:把这些测试结合起来。是的,我已经听过很多次了。。。然而,在许多情况下,依赖关系和工作流都应该得到控制。例如,创建用户、以管理员身份注销、以新用户身份登录、创建报告和验证用户权限的场景。这可能是一个测试用例,但实际上应该是10或15。您不希望整个测试失败,因为创建用户步骤中的电话号码字段有问题。失败的断言将使整个测试用例失败。因此需要工作流和依赖关系。此外,它最小化了重复的代码……@ JackRyan,如果需要考虑将许多测试合并到一个单一的“@测试”中,在那里有太多的断言,然后考虑使用。然后,将执行所有代码(读取断言),然后将发生最终失败。只是一个小问题的建议。@Arran将所有测试放在一个
    @Test
    中是不好的,原因之一正如Jack Ryan提到的,另一个是根据不同的场景测试的可重用性。特别是,在自动化UI测试中,所有这些都与不同的场景有关。在两种不同的场景中,将有一些测试总是很常见的。那么,为什么这些测试的代码应该作为不同的测试重复?@JackRyan我执行了您给出的代码,它按照预期工作。你错过什么了吗?是的,我错过了。TestNG 6.8.3是最新的稳定版本。(6.8.5有一些问题)我没有找到TestNG 6.8.3的预构建jar版本,只是在github发行版上找到了源代码。必须自己建造吗?请再次检查。顺便说一句,我已经用6.8.2、6.8.3、6.8.5进行了测试,最新版本是6.8.7。在所有版本中,依赖项都会中断优先级。值得注意的是,在这种情况下,
    verifyGeneralSettings
    verifyReportingPeriod
    将始终运行,即使
    verifyUserLogin
    失败。如果只有一些依赖项失败,那么似乎没有办法“始终运行”。