首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IRetryAnalyzer为定义为SoftAssert的测试用例生成不正确的结果

IRetryAnalyzer为定义为SoftAssert的测试用例生成不正确的结果
EN

Stack Overflow用户
提问于 2019-09-24 03:56:10
回答 1查看 392关注 0票数 3

我使用IRetryAnalyzer实现了失败测试用例的重试逻辑,在我的测试用例中定义了两种类型的断言-- Assert和SoftAssert。IRetryAnayzer对于正常的断言很好,但是在SoftAssert情况下不像预期的那样工作。以下是有关所面临问题的设想细节:

  • 如果定义为SoftAssert的测试用例在第一次尝试中失败并在下一次尝试中通过,它将继续重试直到最大重试尝试,即使测试用例正在通过。在这种情况下,如果定义为正常断言(非软断言)的下一个测试用例通过,即使它正在通过,它也会被标记为“失败”,并将对定义的最大重试尝试进行重试。
  • 如果将所有测试用例定义为正常断言,它将按预期工作,即,如果它在第一次尝试中失败并通过下一次尝试,它将继续前进,并且不会陷入重试循环。
  • ,如果定义为SoftAssert的测试用例正在传递第一次尝试,则不会重试并转移到下一次测试用例,即它按预期工作。

我需要保留很少的测试用例作为softAssert,因为我必须继续测试运行。例如:

代码语言:javascript
复制
@Test(retryAnalyzer = RetryAnalyzer.class, groups = { "group1" }, priority=1)
    public void TestSection1(){
        Class1.verifyingAppLaunch(); //Defined as Assert
        Class1.Test1(); //Defined as softAssert
        Class1.Test2(); //Defined as softAssert
        Class1.Test3(); //Defined as softAssert
        Class1.Test4(); //Defined as softAssert
        Class1.Test5(); //Defined as softAssert
        softAssert.assertAll();
    }

下面是IRetryAnalyer和ListenerAdapter实现的示例。实现ListenerAdapter是为了删除重复的测试用例执行,这些测试用例被标记为跳过,作为重试实现的一部分。在下面的示例代码中,如果samplecondition1在第一次尝试中失败,即使它在第二次尝试中通过,它也会对定义的最大重试计数进行重试,并将samplecondition2标记为失败,即使它正在传递:

MyTestListenerAdapter.class

代码语言:javascript
复制
import java.util.Iterator;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

public class MyTestListenerAdapter extends TestListenerAdapter {

    @Override
    public void onFinish(ITestContext context) {
        Iterator<ITestResult> skippedTestCases = context.getSkippedTests().getAllResults().iterator();
        while (skippedTestCases.hasNext()) {
            ITestResult skippedTestCase = skippedTestCases.next();
            ITestNGMethod method = skippedTestCase.getMethod();
            if (context.getSkippedTests().getResults(method).size() > 0) {
                System.out.println("Removing:" + skippedTestCase.getTestClass().toString());
                skippedTestCases.remove();
            }
        }
    }
}

TestRetryAnalyzer.class

代码语言:javascript
复制
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class TestRetryAnalyzer implements IRetryAnalyzer {
    int counter = 1;
    int retryMaxLimit = 3;

    public boolean retry(ITestResult result) {
        if (counter < retryMaxLimit) {
            counter++;
            return true;
        }
        return false;
    }
}

TestRetryTestCases.class

代码语言:javascript
复制
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(MyTestListenerAdapter.class)
public class TestRetryTestCases {
SoftAssert softAssert = new SoftAssert();

    @Test(retryAnalyzer = TestRetryAnalyzer.class)
    public void firstTestMethod() {
        System.out.println("First test method");
        if (samplecondition1 == true)
            softAssert.assertTrue(true);
        else
            softAssert.assertTrue(false);
softAssert.assertAll();
    }

    @Test(retryAnalyzer = TestRetryAnalyzer.class)
    public void secondTestMethod() {
        System.out.println("Second test method");
        if (samplecondition2 == true)
            Assert.assertTrue(true);
        else
            Assert.assertTrue(false);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-27 04:43:19

我不知道您正在使用的是哪个版本的TestNG,但我似乎无法使用TestNG 7.0.0 (今天最新发布的版本)重现这个问题。

您的代码中还有另外一个问题。您将SoftAssert作为全局变量。SoftAssert通过它的实现,记住了所有的失败。因此,对于每一次重试,从第一次尝试到现在,它继续坚持所有的失败。这意味着,涉及RetryAnalyser并使用可能出现故障的RetryAnalyserSoftAssert方法将导致该测试方法永远无法通过。

在使用SoftAssert时,应该始终在@Test方法中声明和使用SoftAssert对象,以便实例化它(因此每次重试都会重置)。

下面是您共享的同一个示例(我稍微修改了一下),它演示了这在7.0.0中运行得很好

从输出中可以看到,只有firstTestMethod (它有SoftAssert正在被重试)和secondTestMethod (有一个硬断言并且没有失败)没有被重试。

测试类(我只是改变了这一点,其他一切都是从您原来的文章中借来的)

代码语言:javascript
复制
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.testng.asserts.SoftAssert;

@Listeners(MyTestListenerAdapter.class)
public class TestRetryTestCases {
  int softAssertCounter = 0;
  int hardAssertCounter = 0;

  @Test(retryAnalyzer = TestRetryAnalyzer.class)
  public void firstTestMethod() {
    SoftAssert softAssert = new SoftAssert();
    System.out.println("First test method");
    if (softAssertCounter++ > 2) {
      softAssert.assertTrue(true);
    } else {
      softAssert.assertTrue(false);
    }
    softAssert.assertAll();
  }

  @Test(retryAnalyzer = TestRetryAnalyzer.class)
  public void secondTestMethod() {
    System.out.println("Second test method");
    if (hardAssertCounter++ < 2) {
      Assert.assertTrue(true);
    } else {
      Assert.assertTrue(false);
    }
  }
}

**重试分析器,增加一些日志记录**

代码语言:javascript
复制
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class TestRetryAnalyzer implements IRetryAnalyzer {
  int counter = 1;
  int retryMaxLimit = 3;

  public boolean retry(ITestResult result) {
    if (counter < retryMaxLimit) {
      counter++;
      System.err.println("Retrying the test method " + result.getMethod().getMethodName());
      return true;
    }
    return false;
  }
}

控制台输出

代码语言:javascript
复制
First test method
Retrying the test method firstTestMethod
Retrying the test method firstTestMethod

Test ignored.

First test method


Test ignored.

First test method


java.lang.AssertionError: The following asserts failed:
    did not expect to find [true] but found [false]

    at org.testng.asserts.SoftAssert.assertAll(SoftAssert.java:47)
    at org.testng.asserts.SoftAssert.assertAll(SoftAssert.java:31)
    at com.rationaleemotions.stackoverflow.qn58072880.TestRetryTestCases.firstTestMethod(TestRetryTestCases.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
    at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:584)
    at org.testng.internal.TestInvoker.retryFailed(TestInvoker.java:204)
    at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:58)
    at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:804)
    at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:145)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.testng.TestRunner.privateRun(TestRunner.java:770)
    at org.testng.TestRunner.run(TestRunner.java:591)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:396)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
    at org.testng.SuiteRunner.run(SuiteRunner.java:304)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1180)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1102)
    at org.testng.TestNG.runSuites(TestNG.java:1032)
    at org.testng.TestNG.run(TestNG.java:1000)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:73)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)


Second test method

Removing:[TestClass name=class com.rationaleemotions.stackoverflow.qn58072880.TestRetryTestCases]
Removing:[TestClass name=class com.rationaleemotions.stackoverflow.qn58072880.TestRetryTestCases]

===============================================
Default Suite
Total tests run: 2, Passes: 1, Failures: 1, Skips: 0
===============================================


Process finished with exit code 0
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58072880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档