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 测试。开发人员至少可以通过以下方式使用它们:
开发人员可以分析生成的测试以检测被测软件表现出的意外行为。这是一件非常酷且有价值的事情,但也许它不适合您使用测试 "directly".
许多测试将正确断言预期的行为,并且这些可以在软件的测试套件中按原样使用。生成的整体套件将提供比许多软件更好的防止回归的保护。
即使断言不正确行为的测试也可能有用,不是为了提前检测缺陷,而是为了在通过其他方式检测到缺陷后表征它们。例如,假设您从字段中收到一份报告,指出方法 widget.frob()
引发了意外的 UpYoursException
,但导致它的情况尚不清楚。您的 EvoSuite 测试很可能已经显示至少一种从受影响的方法中引发此异常的方法。这可能不符合使用测试 "directly" 的条件,但它是不尝试提前清除不正确的自动测试用例的理由(也没有修复被测代码)。
底线: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 测试。开发人员至少可以通过以下方式使用它们:
开发人员可以分析生成的测试以检测被测软件表现出的意外行为。这是一件非常酷且有价值的事情,但也许它不适合您使用测试 "directly".
许多测试将正确断言预期的行为,并且这些可以在软件的测试套件中按原样使用。生成的整体套件将提供比许多软件更好的防止回归的保护。
即使断言不正确行为的测试也可能有用,不是为了提前检测缺陷,而是为了在通过其他方式检测到缺陷后表征它们。例如,假设您从字段中收到一份报告,指出方法
widget.frob()
引发了意外的UpYoursException
,但导致它的情况尚不清楚。您的 EvoSuite 测试很可能已经显示至少一种从受影响的方法中引发此异常的方法。这可能不符合使用测试 "directly" 的条件,但它是不尝试提前清除不正确的自动测试用例的理由(也没有修复被测代码)。
底线:EvoSuite 为手写测试用例提供补充,而不是替代它们。