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

时间:2018-08-21 14:34:51

标签: java evosuite

当我学习使用Evosuite时,我写了一些错误的方法。例如,在其中一种方法中,类A的方法直接调用接口B的抽象方法,而EvoSuite为B生成了一个模拟程序,以防止失败:

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生成可能失败的测试用例,从而可以被开发人员直接使用?

1 个答案:

答案 0 :(得分:0)

  

像这些示例一样,EvoSuite的自动生成的测试用例是否总是通过?

EvoSuite网站提供了an extensive list of publications,描述了该软件的理论和操作。归结为最简单的术语,该软​​件会生成测试用例,以检测被测软件中的变异,从而改变其行为并且不受现有测试的束缚。因此,被测软件的实际行为是基准,因此,在未修改的软件上,所有生成的测试都不应失败。

  

如何使EvoSuite生成可能失败的测试用例,从而可以被开发人员直接使用?

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

如果该软件能够先验先验要测试的代码应该做什么,那么该非凡功绩的更好应用就是让它(重新)编写实际代码。

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

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

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

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

最重要的是:EvoSuite提供了对手写测试用例的补充,而不是替代它们。