问题背景
我有几个JUnit测试,例如从目录中获取每个文件并对其执行测试。如果我在TestCase中实现了一个test方法,在一个循环里读取文件做测试,则只会显示一个可能失败或成功的测试。这样的缺点是一旦中间有个测试用例不通过,后面的测试都不会进行了。如何编写TestCase/TestSuite,以便每个文件都显示为单独的测试,即使中间有一个测试失败也不会影响其他测试用例。
解决方法
使用Junit 4的Parameterized/参数化测试。例子:
package yuth.junit.fromFile;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* 从文件读入测试数据,动态构造测试用例。基于jUnit 4,Junit 3下不可用。
* @author yuth
* <p>
* @version 1.0 2018年8月25日
*
*/
@RunWith(Parameterized.class)
public class TestDemo
{
private File file;
@Parameters
public static Collection<Object[]> getFiles()
{
Collection<Object[]> params = new ArrayList<Object[]>();
// 读取测试文件
for (File f : new File(".").listFiles())
{
Object[] arr = new Object[] { f };
params.add(arr);
}
return params;
}
public TestDemo(File file)
{
this.file = file;
}
@Test
public void test()
{
// 实现自己的测试逻辑
assertTrue(!"testFromFile.txt".equals(file.getName()));
}
}
要点:
1.runwith中使用value = Parameterized.class。
2.必须提供@Parameters方法,方法签名必须是public static Collection,不能有参数,并且collection元素必须是相同长度的数组。同时数组元素必须与唯一的公共构造函数的参数数量和类型相匹配。在本例中,我们数组的长度是1,构造方法的参数数量也是1,并且类型都是File。
3.执行test方法,调用了我们提供的参数。
与Spring boot整合时的例子
package yuth.junit.fromFile;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import javax.annotation.Resource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestContextManager;
import com.kingdee.ai.thirdpart.TestLocalIntention;
import com.kingdee.ai.web.Application;
/**
* 简述:从文件读入测试数据,动态构造测试用例。JUNT 4。整合Spring boot
* <p>
* 详细描述:
*
* @author yuth
* <p>
* @version 1.0 2018年8月25日
*
*/
@RunWith(Parameterized.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration
public class TestDemoWithSpringBoot
{
private File file;
private TestContextManager testContextManager;
@Before
public void setUpContext() throws Exception {
this.testContextManager = new TestContextManager(getClass());
this.testContextManager.prepareTestInstance(this);
}
@Parameters
public static Collection<Object[]> getFiles()
{
Collection<Object[]> params = new ArrayList<Object[]>();
// 读取测试文件
for (File f : new File(".").listFiles())
{
Object[] arr = new Object[] { f };
params.add(arr);
}
return params;
}
public TestDemoWithSpringBoot(File file)
{
this.file = file;
}
@Test
public void test()
{
// 实现自己的测试逻辑
assertTrue(!"testFromFile.txt".equals(file.getName()));
}
}