Feed4Junit官方地址:
http://databene.org/feed4junit.html
Feed4Junit自动生成测试数据:
Feed4JUnit 1.1.1 发布了,该版本支持从 CSV 文件中导入完整的 JavaBean 图表。
利用Feed4JUnit能够很方便用随机但校验过的数据执行冒烟测试来提高代码 代码覆盖率和发现由非常特殊的数据结构产生的Bug。此外还可以利用Feed4JUnit轻松定义等价类测试。
官方文档
Defining custom data sources
If you wish to retrieve data from other data source or file types, you can program a connector component, that inherits from the class Feed4JUnitGenerator and provides data:
public static class MyGenerator extends UnsafeMethodParamsGenerator { public Object[] generate() { return new Object[] { 1, 2, 3 }; } } |
The Object array returned by the generate() method is used as parameter list for the invocation of the test method. If the data available from a source is depleted (eg. the end of file is reached), the generator class returns null.
The example class MyGenerator returns { 1, 2, 3 } on each invocation, thus it would be called endlessly, unless you annotate the related test methods with an @InvocationCount for limiting the data volume.
A custom generator class is declared by a @Bean annotation with an id and instructions how to instantiate and initialize the bean object. A @Source annotation at a method referes to its id:
@RunWith(Feeder.class) @Bean(id = "mygen", type = MyGenerator.class) public class BeanSourceTest { @Test @Source("mygen") @InvocationCount(5) public void testArrayIterable(int n1, int n2, int n3) { System.out.println(n1 + ", " + n2 + ", " + n3); } } |
In this case, the type specification tell Feed4JUnit to instantiate an object of the class MyGenerator by its default constructor.
Alternatively, you can make use of Benerator's full feature set regarding bean instantiation, eg. calling a constructor:
@Bean(id = "mygen", spec = "new MyOtherGenerator(1, 'test')") |
or using a bean property contructor:Â
@Bean(id = "mygen", spec = "new MyOtherGenerator{ property1=1, property2 = 'test'}") |
or the more bean-like approach:
@Bean(id = "mygen", type = "MyOtherGenerator", properties = { |
备注:官方文档错误方法这种方式: type = "MyOtherGenerator", 是错误的,不需 type = MyOtherGenerator.class是正确,
最简单的数据源生成器:
package com.easyway.feed4junit; import org.databene.benerator.util.UnsafeMethodParamsGenerator; import org.databene.benerator.wrapper.ProductWrapper; /** * * @author longgangbai * */ public class MyGenerator extends UnsafeMethodParamsGenerator { @Override public ProductWrapper<Object[]> generate( ProductWrapper<Object[]> paramProductWrapper) { return paramProductWrapper.wrap(generate()); } public Object[] generate() { return new Object[] { 1, 2, 3 }; } }
测试代码:
package com.easyway.feed4junit; import org.databene.benerator.anno.Bean; import org.databene.benerator.anno.InvocationCount; import org.databene.benerator.anno.Source; import org.databene.feed4junit.Feeder; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Feeder.class) @Bean(id = "mygen", type = MyGenerator.class) public class BeanSourceTest { @Test @Source("mygen") @InvocationCount(5) public void testArrayIterable(int n1, int n2, int n3) { System.out.println(n1 + ", " + n2 + ", " + n3); } }
需要参数的数据源生成器:
package com.easyway.feed4junit; import org.databene.benerator.util.UnsafeMethodParamsGenerator; import org.databene.benerator.wrapper.ProductWrapper; /** * 构造函数传参可以不需要get/set方法 * @author longgangbai * */ public class MyOtherGenerator extends UnsafeMethodParamsGenerator { private int num; private String test; public MyOtherGenerator(int num,String test){ this.num=num; this.test=test; } @Override public ProductWrapper<Object[]> generate( ProductWrapper<Object[]> paramProductWrapper) { return paramProductWrapper.wrap(generate()); } public Object[] generate() { return new Object[] { 1, 2, 3 }; } }
测试代码如下:
package com.easyway.feed4junit; import org.databene.benerator.anno.Bean; import org.databene.benerator.anno.InvocationCount; import org.databene.benerator.anno.Source; import org.databene.feed4junit.Feeder; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Feeder.class) @Bean(id = "mygen", spec = "new com.easyway.feed4junit.MyOtherGenerator(1, 'test')") public class BeanSourceConstructTest1 { @Test @Source("mygen") @InvocationCount(5) public void testArrayIterable(int n1, int n2, int n3) { System.out.println(n1 + ", " + n2 + ", " + n3); } }
不带构造函数的且带属性的
package com.easyway.feed4junit; import org.databene.benerator.util.UnsafeMethodParamsGenerator; import org.databene.benerator.wrapper.ProductWrapper; /** * 非构造函数传参可以必须需要get/set方法 * UnsafeMethodParamsGenerator * @author longgangbai * */ public class MyOtherGenerator2 extends UnsafeMethodParamsGenerator { private int num; private String test; public MyOtherGenerator2(){ } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getTest() { return test; } public void setTest(String test) { this.test = test; } @Override public ProductWrapper<Object[]> generate( ProductWrapper<Object[]> paramProductWrapper) { return paramProductWrapper.wrap(generate()); } public Object[] generate() { return new Object[] { 1, 2, 3 }; } }
测试类:
package com.easyway.feed4junit; import org.databene.benerator.anno.Bean; import org.databene.benerator.anno.InvocationCount; import org.databene.benerator.anno.Property; import org.databene.benerator.anno.Source; import org.databene.feed4junit.Feeder; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Feeder.class) @Bean(id = "mygen", type = MyOtherGenerator2.class, properties = { @Property(name = "num", value = "1"), @Property(name = "test", value="test") }) public class BeanSourceConstructTest3 { @Test @Source("mygen") @InvocationCount(5) public void testArrayIterable(int n1, int n2, int n3) { System.out.println(n1 + ", " + n2 + ", " + n3); } }