今天在用Junit进行单元测试的时候,遇到一个诡异的问题。测试代码如下:
Java类:Calculate.java
public class Calculate {
public int sum(int var1, int var2) {
System.out.println("Adding values " + var1 + " + " + var2);
return var1 + var2;
}
public int subtract(int var1,int var2){
System.out.println("Subtract values "+ var1+" - "+ var2);
return var1-var2;
}
}
测试类:ParameterizedCalculateTest.java
@RunWith(Parameterized.class)
public class ParameterizedCalculateTest {
private int expected;
private int var1;
private int var2;
public ParameterizedCalculateTest(int expected, int var1, int var2) {
this.expected = expected;
this.var1 = var1;
this.var2 = var2;
}
@Parameters
public static Collection prepareParamters() {
return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 },
{ 7, 3, 4 }, { 9, 4, 5 } });
}
@Test
public void testSum() {
System.out.println("Additions with parameters,first:" + var1 + " and second:" + var2);
Calculate cal = new Calculate();
Assert.assertEquals(expected, cal.sum(var1, var2));
}
}
错误堆栈如下:
java.lang.Exception: No tests found matching Method testSum(com.milan.gjunit.ParameterizedCalculateTest) from org.junit.internal.requests.ClassRequest@739495b8
at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:40)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestMethodReference.<init>(JUnit4TestMethodReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:54)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
刚开始看到异常信息:"java.lang.Exception: No tests found matching Method testSum",猜测难道测试类的方法名要和对应java类中的方法名一样么?试下呗,于是将测试类改为:
@RunWith(Parameterized.class)
public class ParameterizedCalculateTest {
private int expected;
private int var1;
private int var2;
public ParameterizedCalculateTest(int expected, int var1, int var2) {
this.expected = expected;
this.var1 = var1;
this.var2 = var2;
}
@Parameters
public static Collection prepareParamters() {
return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 },
{ 7, 3, 4 }, { 9, 4, 5 } });
}
@Test
public void sum() {
System.out.println("Additions with parameters,first:" + var1 + " and second:" + var2);
Calculate cal = new Calculate();
Assert.assertEquals(expected, cal.sum(var1, var2));
}
}
结果还是不行。。。
果断搜索之,搜到stackoverflow上有类似的问题:
http://stackoverflow.com/questions/12798079/initializationerror-with-eclipse-and-junit4-when-executing-a-single-test/18438718#18438718。
于是乎抱着试试看的想法,扩展Parameterized.Java如下:
public class IDECompatibleParameterized extends Parameterized {
public IDECompatibleParameterized(Class<?> klass) throws Throwable {
super(klass);
}
public void filter(Filter filter) throws NoTestsRemainException {
super.filter(new FilterDecorator(filter));
}
/**
* Running single test in case of parameterized test causes issue as explained in
* http://youtrack.jetbrains.com/issue/IDEA-65966
*
* As a workaround we wrap the original filter and then pass it a wrapped description
* which removes the parameter part (See deparametrizedName)
*/
private static class FilterDecorator extends Filter {
private final Filter delegate;
private FilterDecorator(Filter delegate) {
this.delegate = delegate;
}
@Override
public boolean shouldRun(Description description) {
return delegate.shouldRun(wrap(description));
}
@Override
public String describe() {
return delegate.describe();
}
}
private static Description wrap(Description description) {
String name = description.getDisplayName();
String fixedName = deparametrizedName(name);
Description clonedDescription =
Description.createSuiteDescription(fixedName,description.getAnnotations().toArray(new Annotation[0]));
for(Description child : description.getChildren()){
clonedDescription.addChild(wrap(child));
}
return clonedDescription;
}
private static String deparametrizedName(String name) {
//Each parameter is named as [0], [1] etc
if(name.startsWith("[")){
return name;
}
//Convert methodName[index](className) to
//methodName(className)
int indexOfOpenBracket = name.indexOf('[');
int indexOfCloseBracket = name.indexOf(']')+1;
return name.substring(0,indexOfOpenBracket).concat(name.substring(indexOfCloseBracket));
}
}
PS:装饰器模式用的很赞。。。
然后再把测试类改为:
@RunWith(IDECompatibleParameterized.class)
public class ParameterizedCalculateTest {
private int expected;
private int var1;
private int var2;
public ParameterizedCalculateTest(int expected, int var1, int var2) {
this.expected = expected;
this.var1 = var1;
this.var2 = var2;
}
@Parameters
public static Collection prepareParamters() {
return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 },
{ 7, 3, 4 }, { 9, 4, 5 } });
}
@Test
public void sum() {
System.out.println("Additions with parameters,first:" + var1 + " and second:" + var2);
Calculate cal = new Calculate();
Assert.assertEquals(expected, cal.sum(var1, var2));
}
}
修改点为:
@RunWith(IDECompatibleParameterized.class)
果断Pass。
记录下,顺便对国际友人表示感谢,希望对遇到类似问题的朋友有所帮助。
分享到:
相关推荐
### JUnit参数化测试的使用方法 #### 一、引言 JUnit是Java开发中最常用的单元测试框架之一,它提供了一种简单的方式来编写可重复执行的测试案例。随着软件复杂度的增加,对于某些功能模块可能需要多次使用不同的...
而Junit参数化测试是JUnit框架的一个强大特性,允许我们使用不同的输入数据多次执行同一个测试用例,这对于验证方法在各种边界条件或输入组合下的行为非常有用。下面我们将详细探讨Junit参数化测试的概念、使用方法...
在处理多参数测试时,JUnit提供了一个名为`@Parameterized`的注解,用于创建参数化的测试类。通过这个注解,我们可以为每个测试方法传入一组或多组参数,从而实现对多种情况的覆盖。 FizzBuzz问题是软件面试中常见...
JUnit支持注解、参数化测试、异常测试等特性,使得编写和执行单元测试变得更加简单。 4. **自动化测试**:自动化测试是指通过软件工具自动执行预先编写的测试脚本来检查程序功能是否正确的一种方法。相比手动测试,...
2. **参数化测试(Parameterized Tests)**:`@RunWith(Parameterized.class)`注解允许你为测试方法提供不同的输入参数,执行多次测试,提高了测试覆盖率。 3. **异常测试(Exception Testing)**:`@Test(expected ...
为了更好地组织测试,可以使用`@RunWith`注解配合测试运行器(如`Parameterized`或`Suite`),实现参数化测试和组合测试。参数化测试允许为同一个测试方法提供多组输入数据,而`Suite`则能将多个测试类组合成一个...
此外,JUnit还提供了更高级的功能,如参数化测试(Parameterized Tests),允许使用不同的输入数据运行同一个测试方法;异常测试(Exception Testing),可以通过`@Test(expected = Exception.class)`来检查代码是否...
【基于Junit的ATM测试】是针对自动取款机(ATM)系统进行的一种软件测试方法,它利用Java编程语言以及JUnit测试框架来验证ATM系统的功能正确性。JUnit是一个广泛使用的Java单元测试框架,它允许开发者编写可重复运行...
1.seleRrj是工程包,包含简单的自动化测试demo以及jar包,已经加入junit4支持;调试运行通过; 2.selenium-fireFox插件,安装在火狐浏览器里面 用于录制自动化脚本和学习自动化测试; 3.我用的火狐版本是v21.0版本,...
IDEA JUnit5测试套件运行错误的问题是指在使用IDEA 2017.3版本中,建立JUnit5的测试用例时,出现“java.lang.Exception: No runnable methods”的错误,这个问题是由于JUnit 5和JUnit 4的测试套件机制不同引起的。...
单元测试之道(Java):使用JUnit进行单元测试。单元测试是提高代码质量的有效手段,但大部分开发人员由于种种原因都不乐意进行单元测试。
Unit是一个Java语言的单元...Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。
总结一下,JUnit4是一个强大的单元测试框架,它的注解驱动使得测试代码更简洁,断言机制便于检查代码行为,参数化测试、异常测试、分类和分组等功能则提高了测试的灵活性和覆盖率。通过合理使用JUnit4,开发者能够...
总的来说,Junit4.12为Java开发人员提供了强大的单元测试能力,其注解驱动的模型、丰富的断言方法、参数化测试和分类等功能使得测试代码更加简洁、易于维护。正确理解和使用Junit4.12,对于确保代码质量和提升开发...
这是JUnit的一个稳定版本,发布于2014年,提供了许多新特性,如注解(Annotations)、参数化测试、异常断言等。对于开发人员来说,这些特性使得编写和执行测试用例变得更加简洁和直观。例如,使用`@Test`注解标记...
除了基础功能外,Junit还支持参数化测试、假设测试、定时器等高级特性,以满足不同测试需求。参数化测试允许对同一测试用例使用不同的输入数据,而假设测试允许在不满足特定条件时跳过测试。定时器则可以设置测试...
5. **参数化测试**:`@Parameterized`测试可以使用不同的参数多次运行同一个测试方法,这对于测试多种输入情况非常有用。 6. **超时测试**:`@Test(timeout = 1000)`可以设置测试方法的执行时间限制,超过设定时间...
8. **参数化测试**:Junit 4引入了参数化测试,允许你为同一个测试方法提供多组输入数据,测试方法将为每组数据执行一次。 9. **假对象和模拟**:在单元测试中,有时需要隔离被测试的代码,避免与外部系统的交互。...