EvoSuite如何生成失败的测试用例?

How can failing test cases be generated via EvoSuite?

我在学习使用Evosuite的时候,写了一些错误的方法。比如其中一个classA的方法直接调用了接口B的抽象方法,EvoSuite为B生成了一个mock来避免case失败:

import org.junit.Test;
import static org.junit.Assert.*;
import static org.evosuite.shaded.org.mockito.Mockito.*;
import MockTest.A;
import MockTest.B;
import org.evosuite.runtime.EvoRunner;
import org.evosuite.runtime.EvoRunnerParameters;
import org.evosuite.runtime.ViolatedAssumptionAnswer;
import org.junit.runner.RunWith;

@RunWith(EvoRunner.class) @EvoRunnerParameters(useVNET = true, separateClassLoader = true, useJEE = true) 
public class A_ESTest extends A_ESTest_scaffolding {

  @Test(timeout = 4000)
  public void test0()  throws Throwable  {
      A a0 = new A();
      B b0 = mock(B.class, new ViolatedAssumptionAnswer());
      doReturn((String) null).when(b0).get(anyInt());
      String string0 = a0.test(b0);
      assertNull(string0);
  }
}

对于可能出现被零除的方法,EvoSuite生成的测试用例甚至会捕获异常以确保测试用例通过:

import org.junit.Test;
import static org.junit.Assert.*;
import static org.evosuite.runtime.EvoAssertions.*;
import org.evosuite.runtime.EvoRunner;
import org.evosuite.runtime.EvoRunnerParameters;
import org.junit.runner.RunWith;
import test.Case2;

@RunWith(EvoRunner.class) @EvoRunnerParameters(useVNET = true, separateClassLoader = true, useJEE = true) 
public class Case2_ESTest extends Case2_ESTest_scaffolding {

  @Test(timeout = 4000)
  public void test8()  throws Throwable  {
      Case2 case2_0 = new Case2();
      // Undeclared exception!
      try { 
        case2_0.add(6, 0);
        fail("Expecting exception: ArithmeticException");

      } catch(ArithmeticException e) {
         //
         // / by zero
         //
         verifyException("test.Case2", e);
      }
  }
}

EvoSuite 自动生成的测试用例是否总是通过这些示例?如何让EvoSuite生成可以失败的测试用例,让开发者直接使用?

Are EvoSuite's automatically generated test cases always passing, as in these examples?

EvoSuite 站点提供 an extensive list of publications 描述该软件的原理和操作。然而,归结为最简单的术语,该软​​件会生成测试用例,这些用例会检测被测软件中的 突变 ,这些变化会改变其行为并且不会被现有测试捕获。因此,被测软件的实际行为是基线,因此 none 生成的测试应该在未修改的软件上失败。

How can EvoSuite be made to generate test cases that can fail, and thus can be directly used by developers?

我不知道 任何 软件怎么可能。 EvoSuite 应该如何将软件的任何特定行为识别为不正确,从而生成失败案例?考虑你的除以零的例子。当其第二个参数为 0 时,被测方法显然会抛出一个 ArithmeticException。EvoSuite 应该如何知道这不是该方法应该做的事情?

如果软件能够辨别先验被测代码应该做什么,那么更好地应用这一非凡的壮举就是让它(重新)编写实际代码。

但这并不意味着开发人员不能使用 EvoSuite 测试。开发人员至少可以通过以下方式使用它们:

  1. 开发人员可以分析生成的测试以检测被测软件表现出的意外行为。这是一件非常酷且有价值的事情,但也许它不适合您使用测试 "directly".

  2. 许多测试将正确断言预期的行为,并且这些可以在软件的测试套件中按原样使用。生成的整体套件将提供比许多软件更好的防止回归的保护。

  3. 即使断言不正确行为的测试也可能有用,不是为了提前检测缺陷,而是为了在通过其他方式检测到缺陷后表征它们。例如,假设您从字段中收到一份报告,指出方法 widget.frob() 引发了意外的 UpYoursException,但导致它的情况尚不清楚。您的 EvoSuite 测试很可能已经显示至少一种从受影响的方法中引发此异常的方法。这可能不符合使用测试 "directly" 的条件,但它是不尝试提前清除不正确的自动测试用例的理由(也没有修复被测代码)。

底线:EvoSuite 为手写测试用例提供补充,而不是替代它们。