본문 바로가기

Java

[Java] Interface. - 아주 간단한 테스트 프레임웍 만들어보기 2 -

앞선 포스트에서 테스트 프로그램을 만들어서 돌리는 간단한 프로그램을 만들었습니다.
물론 내부 로직은 다 빠지고 형태만 보여주기 위한 코드였고요..

최종적으로 나온 Tester.java 의 모습은 아래와 같았습니다.



2개의 테스터 클래스가 보입니다. 내부로직으로 구현되어 있지는 않지만
ProductListsComapreTester.java는 상품 리스트를 검색해서 그 정렬 순서가 원하는 순서대로
정렬되어 있는지 확인하는 Tester 클래스입니다.

ProductRankScoreTester.java는 다른 두개의 검색 서버가 있다고 가정 할 때 각각의 서버에 검색을 하고
그 두개의 결과가 일치하는지 확인하는 Tester 클래스입니다. 물론, 내부 로직은 구현을 하지 않았습니다.

일단, 앞에서 이제 인터페이스를 사용한다고 하였는데
Tester.java를 보시면 어떻게 인터페이스를 만들면 좋을지 대충 짐작도 되실겁니다.

바로 만들어서 그 인터페이스를 사용해보겠습니다.


ProductTester.java
그리고, 이를 구현하도록 위 두개의 테스터 클래스를 수정해보겠습니다.


ProductRankScoreTester.java ProductListsCompareTester.java
이미 isPassed라는 이름의 메서드를 공통적으로 가지고 있었기 때문에 쉽게 수정이 가능합니다. 그럼,
Tester.java는 어떻게 바뀔까요?


Tester.java
각 구현체 클래스를 사용 해 참조 변수를 선언하던 부분이 인터페이스를 사용하여 선언하는 것으로 수정되었습니다.
이 상태로 후배에게 "어떤 이점이 있을 것 같아?" 라고 얘기했더니 tester라는 참조 변수를 재사용 할 수 있다. 라고 대답
하더군요...

ProductTester tester = new ProductListsCompareTester();
boolean isPassed = tester.isPassed();
tester = new ProductRankScoreTester();
isPassed = tester2.isPassed();

"재사용하면 뭐가 좋은데?" 라고 하니
"메모리... " 우물쭈물 대답하더군요...

재사용하는 것은 객체여야하지 변수를 재사용하는 것은 이득이 없다라고 얘기 해주고.. 또, 객체도 어지간히 크거나 무거운 객체가 아니며 재사용 하는 것이 아주 눈에 띄는 성능 향상을 가져오지 않는다고 얘기해주었습니다.

개인적으로는, 변수의 재사용을 잘 하지 않는 편입니다.

아무튼.. 변수의 재사용이 중요한 것이 아니라 참조 변수를 선언하는 데 사용한 타입 (ProductTester 인터페이스)이 같다는 것이
중요한 것 입니다.

테스트를 하기 위한 로직은 ProductTester 인터페이스를 구현한 각각의 구현 클래스들이 알아서 가지고 있고,
외부에서는 isPassed라는 메서드를 통해 그 테스트 결과가 통과인지 실패인지를 알 수만 있으면 됩니다.
그것이 이번에 간단하게 만들어보려고 하는 테스트 프레임워크 (라고 이름 붙이기도 민망한..)의 핵심입니다.

그럼, 인터페이스를 사용하였으니 이를 사용해서 Tester 클래스들을 모두 가져와서
일괄적으로 테스트를 실행 할 수 있는 MultiTester를 만들어보겠습니다.


MultiTester.java
인터페이스를 사용했기 때문에 ProductTester라는 Type을 갖는 List를 사용하여 모든 Tester 클래스를 받고
이를 사용해서 테스트를 일괄적으로 수행하고 있습니다.
addTester메서드의 파라메터가 ProductTester인것과 isAllPassed 메서드의 for문에 마찬가지로 ProductTester 인터
페이스가 사용 된 것을 잘 보시고요...

그럼 이것을 어떻게 사용 할까요?


Tester.java
테스터 클래스들이 같은 인터페이스를 구현하고 있기 때문에
MultiTester는 위 처럼 다른 구현 클래스를 하나의 ProductTester로써 가질 수 있게 됩니다.

테스터 클래스는 현재 사용하고 있는 Service나 Controller 혹은 DAO를 사용하여
테스트를 수행하도록 되어 있다고 가정해보면..
위 Tester를 하루에 한번씩 돌리도록 스케쥴을 지정하고 그 결과로 메일로 발송하게 되면
누군가 Service나 DAO의 로직을 잘못 수정했을 때 위 테스터에 의해서 그 결과를 바로 받을 수 있을 것 입니다.

이게 아주 초보적인 테스트 자동화라고 볼 수도 있겠죠..

만약에 서비스 클래스가 늘어나서 그 서비스 클래스를 테스트 하기 위한 테스터를 만들어
위 자동 테스터 프레임워크에 적용하고 싶다면?

간단합니다..
ProductTester 인터페이스를 구현하고, 이를 MultiTester에 add만 해주면 되는 것이죠..



NewServiceTester.java Tester.java
Tester에 저렇게 추가만 하면 되지요...

그런데, 테스터가 추가 될 때마다 Tester 클래스를 수정해줘야 하는 것은 조금 귀찮을 수 있습니다.
다음에는 이것을 프로퍼티를 사용해서 클래스 수정 없이 테스터를 추가해주는 것을 보겠습니다.

reflect에 대한 이야기가 나오겠고요...

그 이후에는 Annotation을 사용해서 아예 프로퍼티 조차 수정하지 않아도
테스터가 적용 되도록 해보겠습니다....