테스트 잘할 수 있어(주제)
또 스프링의 핵심이 추가되었다. 테스트! (생각보다 핵심이 좀 많네
) 테스트를 왜 잘 해야 할까? 테스트는 왜 필요하지? 귀찮은데? 라는 의문을 수도 없이 필자는 품어 왔다. 왜냐하면 오래 걸리는 작업이라서... 하지만 다른 개발자들, 토비의 스프링을 통해서 테스트가 왜 중요한지 조금 알았다. 그래서 이번 주제는 “테스트를 어떻게 작성할지, 테스트를 쉽게 해주는 도구는 뭐가 있는지” 알아보려고 한다!
토비의 스프링에서 테스트에 관련한 주제들
1장 다시 보기(서론)
토비의 스프링의 1장 내용과 유사한 글귀를 가져왔다. 본 내용은 백기선님의 블로그에서 가져온 내용이다.
IOC는 제어권을 프레임웤에 넘기는 포괄적인 개념이다.
여기서 제워권이란 새로운 객체의 생성, 트랜잭션, 보안에 대한 제어들을 이야기 한다.
AOP는 IOC를 실현하는 하나의 기술이다.
DI또한 IOC를 실현하는 하나의 기술이다.
DI는 종속성을 필요로 하는 코드 없이 여러 클래스들을 묶는데 사용하는 기술입니다.
클라이언트는 프레임웤에게 종속성의 생명주기 관리를 넘겼습니다.
이렇게 함으로써 클라이언트는 테스트하기 용이해 집니다.
Dependency Injection은 Inversion Of Control의 한 종류이다. 이것은 코드에 종속성을 주입하는 원리이다. 이것을 사용하면 객체 생성 또는 그것을 위치시키는 일을 프레임웍에게 전가 시키기 때문에 코드 자체의 테스트가 용이해진다.
ApplicationContext는 Spring의 주요 객체 레지스트리와 통합 포인트다. 주로 XML파일을 통해서 bean과 그들의 종속성을 설정한다. 많은 기능이 있지만 그 중에 객체 생성과 DI가 핵심 기능이다.
마지막으로 POJO 스타일로 개발이 가능하다는 것이다. 따라서 객체 지향 개발 기술의 사용이 가능하며 POJO로 개발 된 시스템은 테스트가 용이하고 유연하다. 또한 개발자들이 프레임웤을 어떻게 다루는지 보다는 문제 영역과 비즈니스 로직에 집중하여 개발이 가능해진다.
음... 내가 바라보는 토비의 스프링 내용이 맞나...
백기선님의 글에서 많이 언급되는 내용은 테스트다. 무려 3번이나 언급되었다. 그만큼 Spring이 지향하는 가치에는 테스트가 포함되어있다는 것이다. 그럼 도대체 “테스트는 뭘까?”
테스트?(개념)
필자가 테스트를 공부하며 느낀 점은 “테스트가 뭐냐”에 대한 질문에 답은 “내가 만든 코드가 원하는 결과를 만들어 주는지 평가할 수 있는 존재”이다.
이러한 평가를 어떻게 만들어야 할까?(테스트를 만드는 개념적 방법)
테스트를 만드는 방법은 전체 테스트를 구성하는 방법과 하나의 테스트를 구성하는 방법 2가지로 나누어 생각할 수 있다.
•
테스트 전체를 구성하는 방법
항상 실패하는 테스트를 먼저 작성
테스트에 통과하는 프로덕션 코드 작성
테스트가 통과하면 프로덕션 코드를 리팩토링
•
단위 테스트를 구성하는 방법
given (준비) 테스트에 필요한 데이터를 셋팅하는 단계
when (실행) 직접 실행하는 단계
then (단언, 결과확인) 단언문(asserT,assertThat 등)을 통해 success, fail결과를 유도, 판단하는 단계
이러한 평가를 어떻게 만들어야 할까?(단위 테스트를 만드는 방법)
우리에게 지금 필요한 것은 “테스트를 본질적으로 어떻게 만드느냐” 이다. 실제 테스트는 given, when, then 단계를 만들면 된다. 단위 테스트의 통상적인 규칙인 클래스 수준으로 나누어 테스트를 만들었다.
테스트 할 예제 코드
테스트 코드
테스트가 주는 장점?
만약 예제 코드에서 요구 사항 또는 오류가 발생되어 그 부분을 찾고 수정해야 한다고 가정해보자.
요구사항
”0/0 이 오류가 나요”
테스트가 없다면?
테스트가 있다면?
이 외에도 테스트가 주는 장점?
•
서버를 실행하는 등의 시간을 절약할 수 있다(당연히 테스트 코드만 돌리기 때문에).
•
필요한 데이터를 미리 기입하고, 테스트가 끝나고 정리하는 등의 행동이 자동화되어 있다.
•
단위 테스트의 경우 테스트가 매우 빠르다(계산기 기준 메서드 단위로 테스트 하기 때문에 테스트 속도가 매우 빠르다).
•
문서로서의 역할이 가능하다(코드의 동작이 given, when, then의 순서로 이루어져 코드의 흐름과 결과 파악이 용이해진다).
알아두면 좋은 테스트 코드 테스트 코드 F.I.R.S.T 원칙
•
fast
빠르게 실행 되어야 한다(잘 분리해서 베이스케이스에서 실행되도록 만들어야한다).
•
independent
단위 테스트는 객체의 상태, 메서드, 이전 테스트 상태, 다른 메서드의 결과 등에 의존해서는 안된다. 따라서 단위테스트는 어떠한 순서로 실행하더라도 성공해야 한다(plus,minus 의 순서가 바뀌어도 테스트 결과에 영향이 있어선 안된다. 즉, 단위로 쪼갠 테스트 케이스의 순서가 바뀌어도 결과는 보장되어야 한다.).
•
repeatable
반복 가능해야한다.
•
sellf-validating
자체 검증이 가능해야한다. 수동 확인이 불필요하고 테스트가 실행성공 여부를 판단할 수 있어야한다.
•
timely
단위 테스트가 선행되고 난 이후 제품 코드를 작성해야한다(현실적으로는 어려울 수 있다).
물론 테스트 코드는 이것보다 더 많은 과정이 필요하다. 하지만 생략한 점이 많다. 필자가 보여주고 싶었던 것은 테스트 코드의 대략적인 작성 방법론과 테스트 코드의 효용이다. 이 예제를 통하여 테스트 코드를 대충 어떻게 작성하고 어떻게 활용하고 내 코드에 어떤 영향을 주는지 알았다.
테스트를 도와주는 도구들?(Junit)
스프링은 테스트 코드를 작성을 더욱 쉽게 도와준다. 스프링을 쓰는 것 만으로도 충분히 오브젝트를 관심사 별로 잘 분리할 수 있다. 또한 DI를 통하여 기존 계산기에서 만든 static한 변수들을 제거할 수 있다. 더더더더더 좋은 테스트 코드를 만들 수 있다는 것이다. 이제부터는 스프링이 지원해주는 Junit을 좀 더 알아보자
Junit?
Junit5?
테스트 작성해보기
더 자세하게 알아보기(설명을 다 적을 수 없을 만큼 많은 기능을 가지고 있다)
테스트를 도와주는 도구들?(Mockito)
Mockito가 남아있다. 기존 junit을 사용하면서 좋았던 점은 spring과 연계한 DI기능의 활용과 컨테이너 사용이다. 근데 생각해보면 단위 테스트에서 모든 빈을 등록하고 이를 통하여 객체를 평가하려니 작업이 많았다. 그래서 Mock을 이용한 가짜 객체를 이용하여 junit의 테스트에 더욱 힘을 실어 준 것이다.
Mockito?
예시 상황?
Mock을 통해서 이룰 수 있는 것?
더 자세하게 알아보기(설명을 다 적을 수 없을 만큼 많은 기능이 있다)
정리
1.
테스트는 “내가 만든 코드가 원하는 결과를 만들어 주는지 평가할 수 있는 존재”이다.
2.
통합 테스트, 단위 테스트로 테스트의 종류를 나눌 수 있다.
3.
단위 테스트를 작성 할 때는 given, when, then의 형태로 만들어야 한다.
4.
테스트는 귀찮은 존재가 아니다. 분명 장점이 있고 그 장점으로도 테스트를 작성해야 할 이유가 분명하다.
5.
좋은 테스트 코드는 빠르고, 결과가 보장되며, 반복할 수 있고 검증할 수 있는 테스트 코드다.
6.
테스트 코드를 더 잘 작성할 수 있도록 Spring 에서는 Junit과 Mockito를 지원해준다.
7.
Junit을 통해서 테스트 코드를 분리할 수 있고 단언문 사용이 가능하며 스프링의 온전한 기능도 같이 사용할 수 있다.
8.
Junit에서도 구성을 나눌 수 있었다. 테스트 클래스, 테스트 메서드, 라이프사이클 메서드 이것을 잘 활용하는 것이 중요하다(의존적이지 않게, 1장에서 배운 오브젝트를 잘 설계한 상태로).
9.
Junit만 활용할 수 있지만 Mock을 이용하여 가짜 의존 관계를 넣음으로 자칫하면 통합 테스트가 될 수 있는 객체를 단위 테스트로 작성할 수 있었다.
10.
Mockito도 결국 단위 테스트를 위해서 만들어진 것이다. 더욱 내 객체가 잘 동작하는지 평가하기 위한 프레임워크다.
체크 리스트
주제 : (테스트를 잘할 수 있다. 이를 주제로 테스트란 무엇인지, 테스트에는 어떤 것이 있는지, 어떻게 만들어야 하는지 등을 설명하고 싶었다.)
원리 및 개념 : (테스트의 구성, 단위 테스트를 만드는 방법 등을 설명하고 싶었다. 실제 코드 보다는 테스트를 어떻게 구성해야 하는지에 대해서 초점을 맞췄다.)
방법 : (구성 방법은 계산기 예제를 통하여 보여주고 싶었고 장점도 같이 설명하고 싶었다. 또한 전혀 라이브러리, 프레임워크의 도움없이 테스트를 만들고 그 후에 프레임워크의 도움을 통하여 어떻게 테스트를 구성할지 설명하고 싶었다.)