前面介绍了测试套件TestSuite的概念和基本功能是把需要测试的测试类加进来管理,像一个容器一样。这样管理方式有些简单粗暴,为了达到更精细和灵活管理,我们这篇来学习一个Categories的概念,字面意思就分类。
1.Categories
这个分类和测试套件很像。
第一个特点,在TestSuite原来的注解变了,第二个我们需要在原来的TestClass里面是有Catogories注解。category既可以作用在方法,也可以作用在类上,我们习惯写在class 名称前一行,写在方法前一行不常用,一般一个class,我们做一个类型测试,一个业务场景类型。
2.Category demo练习
我们有两个测试类,我们把HelloJunitTest.java分类成A.class, 把PreteinTrackingTest.java分类成A.class, 只把前面文章写过的Timeout这个用例注释为B.class, A.class表示成功的用例集合,B.class表示失败的,A B都是接口。
搜先,我们需要提前创建一个Catogory的一个接口,用来后面分类使用,这个就是A.class
注意,这是一个接口,目前我们这个接口什么代码都不写。
package test;
public interface GoodCategoryTest {
}
然后创建一个BadCatoryTest接口
package test;
public interface BadCategoryTest {
}
然后开始使用Category注解在测试类中标注
package test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@Category(GoodCategoryTest.class)
public class HelloJunitTest {
@Test
public void test() {
assertEquals(5, "Hello".length());
}
}
来看第二个测试类,由于我需要把里面一个方法标注成B.class,所以只能每个方法上都添加Category注解。
package test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import com.anthony.protein.InvalidGoalException;
import com.anthony.protein.TrackingService;
public class TrackingServiceTests {
private TrackingService ts;
@BeforeClass
public static void before() {
System.out.println("Before class, Onln Once");
}
@AfterClass
public static void after() {
System.out.println("After class, only once");
}
@Before
public void setup() {
System.out.println("Before Method");
ts = new TrackingService();
}
@After
public void tearDown() {
System.out.println("After Method");
}
@Test
@Category(GoodCategoryTest.class)
public void newTrackingServiceTotalIsZero() {
assertEquals("Tracking service total was not zero", 0, ts.getTotal());
}
@Test
@Category(GoodCategoryTest.class)
public void whenAddingProteinTotalIsIncreaseByAmount() {
ts.addProtein(10);
assertEquals(10, ts.getTotal());
}
@Test
@Category(GoodCategoryTest.class)
public void whenRemovingProteinTotalRemainsZero() {
ts.removeProtein(5);
assertEquals(0, ts.getTotal());
}
@Test(expected=InvalidGoalException.class)
@Category(GoodCategoryTest.class)
public void testExceptionThrow() throws InvalidGoalException {
ts.setGoal(-5);
}
@Test(timeout=20)
@Category(BadCategoryTest.class)
public void badTest() throws InvalidGoalException {
for(int i=0; i < 1000000000; i++) {
ts.setGoal(1);
}
}
}
这个时候TestSuite这样写
package test;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Categories.class)
@IncludeCategory(GoodCategoryTest.class)
@Suite.SuiteClasses({
HelloJunitTest.class,
TrackingServiceTests.class
// 接着写其他被测单元测试类
})
public class ProteinTrackerSuite {
}
执行下这个TestSuite文件
这种场景,我们还可以利用取反策略来跑用例,这里我们的场景是只执行Good的测试用例,取反就是除Bad之外的,我们需要利用注解@IncludeCategory相反的作用的,叫做@ExcludeCategory,就是除...之外,测试套件注解这么写,也是可以达到上面一样的运行结果。
package test;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.ExcludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Categories.class)
@ExcludeCategory(BadCategoryTest.class)
@Suite.SuiteClasses({
HelloJunitTest.class,
TrackingServiceTests.class
// 接着写其他被测单元测试类
})
public class ProteinTrackerSuite {
}
也就是只执行类GoodCategoryTest这个分类的用例,我把测试套件改成只执行BadCategoryTest.class
package test;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Categories.class)
@IncludeCategory(BadCategoryTest.class)
@Suite.SuiteClasses({
HelloJunitTest.class,
TrackingServiceTests.class
// 接着写其他被测单元测试类
})
public class ProteinTrackerSuite {
}
运行下
只执行这个标注为BadCategoryTest.class的用例,这个是期待的效果。