同一个测试类内部或者不同测试类之间的@Test
执行顺序
JUnit4.11之后提供了MethodSorters,在测试类上加注解@FixMethodOrder(value)
可以有三种方式对test执行顺序进行指定,如下:
默认(MethodSorters.DEFAULT),按方法名(MethodSorters.NAME_ASCENDING)和JVM(MethodSorters.JVM)
- 默认顺序由方法名hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定,不同操作系统可能顺序不同;
- 按方法名称的进行排序,由于是按字符的字典顺序,所以以这种方式指定执行顺序会始终保持一致; 不过这种方式需要对测试方法有一定的命名规则,如 测试方法均以testNNN开头(NNN表示测试方法序列号 001-999)
单元测试的目的就是测试最小单位的正确性,隔离和其他部分的关联,自然也不能有依赖,不然,一定测试通不过,你无法知道是单元内部的问题,还是外部环境的问题。所以我们仅仅在
blog表
的测试中使用了这种排序规则 - 按JVM返回的方法名的顺序执行,此种方式下测试方法的执行顺序是不可预测的,即每次运行的顺序可能都不一样(JDK7里尤其如此).
实际上 Junit里是通过反射机制得到某个Junit里的所有测试方法,并生成一个方法的数组,然后依次执行数组里的这些测试方法; 而当用annotation指定了执行顺序,Junit在得到测试方法的数组后,会根据指定的顺序对数组里的方法进行排序;
不同的测试类之间有重复的操作,如何保证测试数据不互相影响
由于Junit4
不同测试(即每一个@Test
都是一个单独的单元测试,每个测试方法执行前都会重新实例化测试类)的默认执行顺序是按照方法名的hash值
排序,没有并行测试。
所以可以用@Transactional
注解每个测试类,测试类内部如果没有设置事务,则默认和类相同。那么在测试中,只要我们不提交事务,Spring默认会测试完毕回滚,因此不同的测试单元之前数据互不影响。
特别注意:在test
中,Spring默认测试结束就会回滚,如果不想回滚,可以用@Rollback(false)
注解;
而在一般的Java类中,Spring默认只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚,我们可以用@Transactional
注解的rollbackFor
属性设置其他的
DAO层的测试一般insert在最前面,delete在最后,不同的测试单元之间数据需要互相使用,怎么办?
解决1(不推荐):利用@FixMethodOrder(MethodSorters.NAME_ASCENDING)
注解设定按照方法名字典顺序执行测试,可以按照下面的命名方式:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyBlogApplication.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BlogMapperTest1 {
@Autowired
private BlogMapper blogMapper;
@Autowired
private UserMapper userMapper;
@Test
public void test1InsertBlog() throws Exception {
}
@Test
public void test2SelectBlogByUserUuid() throws Exception {
}
@Test
public void test3DeleteBlogByBlogUuid() throws Exception {
}
}
解决2: 每个单元测试都重新构造数据。。。当增删改查很多时,为了保证测试类的清晰,推荐这种方法。
解决3: 把你需要共享数据所有操作放到一个@Test
注解的方法中,比较适合操作比较少的测试。