오타가 나면 안 된다.
test로 시작해야하는데 실수로 이름을 tsetSafetyOverride로 지으면 테스트 메서드로 인식하지 못하고 테스트를 수행하지 않음
올바른 프로그램 요소에서만 사용되리라 보증할 방법이 없다.
JUnit3의 명명 패턴인 'test'를 메서드가 아닌 클래스의 이름으로 지음으로써 해당 클래스의 모든 테스트 메서드가 수행되길 바랄 수 있지만 개발자가 의도한 테스트는 전혀 수행되지 않음
프로그램 요소를 매개변수로 전달할 마땅한 방법이 없다.
특정 예외를 던져야 성공하는 테스트가 있을 때, 메서드 이름에 포함된 문자열로 예외를 알려주는 방법이 있지만 보기 흉할 뿐 아니라 컴파일러가 문자열이 예외 이름인지 알 수 없음
/**
* @Test
* 테스트 메서드임을 선언하는 애너테이션
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test{}
// 마커 애너테이션 처리기
public class RunTests {
public static void main(String[] args) throws Exception {
int tests = 0;
int passed = 0;
Class<?> testClass = Class.forName(args[0]);
for (Method m : testClass.getDeclaredMethods()) {
if (m.isAnnotationPresent(Test.class)) {
tests++;
try {
m.invoke(null);
passed++;
} catch (InvocationTargetException wrappedExc) {
Throwable exc = wrappedExc.getCause();
System.out.println(m + " 실패: " + exc);
} catch (Exception exc) {
System.out.println("잘못 사용한 @Test: " + m);
}
}
}
System.out.printf("성공: %d, 실패: %d%n",
passed, tests - passed);
}
}
리플렉션을 이용하여 마커 애너테이션을 찾고, 예외 발생 시 InvocationTargetException으로 Wrapping 되어 해당 예외에 담긴 실패 정보를 추출해서 출력함