[JUNIT] 실행순서

JAVA 2014. 4. 17. 18:59

빌드를 기다릴때 가끔 블로그가 생각난다.. 

Junit 의 @Test 메서드의 수행 순서는 정해져 있지않다. 

이번 버전 소스는 봐도 의미가 없으므로 4.11 버전을 보자. 

Junit 4.11 버전 부터는
@FixMethodOrder(MethodSorters.TYPE) 를 이용하여 메서드 수행 순서를 정할 수 있다.

MethodSorters.JVM: the order in which the methods are returned by the JVM, potentially different order each time
MethodSorters.DEFAULT: deterministic ordering based upon the hashCode
MethodSorters.NAME_ASCENDING: order based upon the lexicographic ordering of the names of the tests.

1. MethodSorters.DEFAULT 는 test 대상 class의 getDeclaredMethods() 을 통해 메서드를 얻어온두 

method객체 의 getname 을 hashcode() 한 값으로 sort하여 메서드의 실행 순서를 정한다. 

2. MethodSorters.NAME_ASCENDING 은 말대로 method객체의 getname() 을 이용해 sorting 

3. MethodSorters.JVM 은  getDeclaredMethods() 에서 넘어오는 그대로 전한다. 


문제는 클래스의 모든 method 객체를 가져오는 getDeclaredMethods()  요놈인데 순서가 지멋대로 이다. 

junit을 4.11을 사용하거나 JDK 7 에서 순서가 뒤집히는 경우를 당할 수 있다. 


처음부터 메서드 이름을 순서를 생각 않고 작성했는데 메서드 실행 순서가 중요하고그런 테스트 케이스가 1000개 이상이라면 대략 당황스럽다. 


귀찮아서 일단 검색하다 멋진 아저씨를 발견.

http://intellijava.blogspot.de/2012/05/junit-and-java-7.html


이 아저씨의 아이디어는  getDeclaredMethods()로 가져온 method 를 컴파일된 class에서 byte 코드를 분석하여

linenumber와 index를 알아오고 그걸로 sorting 하는 멋진 방법이다. 


고대로 따라해서 되면 다행이지만 2% 부족한 부분이  linenumber를 가져오는 부분이다. 

저거보다는 ASM 이나 javassist, BCEL 를 이용하면 좋다. 


ASM은 예제부터가 어렵고 코드가 길어서 만만한 javassist로 linenumber를 구해왔다. 

javassist는 powerrmokito에 dependency가 있으니 powerrmokito를 이용한다면 javassist를 쓰자.


이랗게 하고 테스트를 마치고 흡족해 하였으나. 

몇가지 부족한 점이 보였다. 


1. @FixMethodOrder 를 안먹는다. (이부분은 새로운 타입을 추가하면 간단할듯.)

2. SpringJUnit4ClassRunner 수정한 부분을 타지 않는다. 

3. Maven-surefire-plugin useSystemClassLoader false 설정일때 클래스를 찾지못한다. 

   useSystemClassLoader 설정은 2.4 부터인가 기본설정이 true로 바뀌었다. 


나머지는 별문제가 되지않지만 2번문제는... 난감.. 

당황하지 않고  새로운 클래스를 만든뒤 SpringJUnit4ClassRunner를 상속하고 sorting하는 부분만 오버라이드 하고 돌려보니 성공. 

하지만 @TransactionConfiguration 등 스프링에서 제공하는 기능을 쓸때 안되는 문제가 발견 되었다.

걍 맘편히 BlockJUnit4ClassRunner 에 구현하면 해결 될듯하다. 근데 다 하고 나니까 이게 귀찮다.. 









Posted by 마법수정화살
,