2 분 소요

테스트 코드의 중요성

테스트 코드의 작성 이유

a.기능의 추가, 변경, 삭제에 대처하고 자동화 테스트를 위해

b.예상하지 못한 오류에 대한 피드백을 위해

c.좋은 설계로 작성되게끔 코드를 유도(테스트를 편하게 하려면 결국 객체지향적 코딩을 해야 한다)

d. 기능 정의의 문서의 역할

e. 실수를 줄여준다


a) 기능의 추가, 변경, 삭제에 대처하고 자동화 테스트를 위해

프로젝트에서 코딩을 할 때 최초의 기획의도와 다르게 기능이 변경되는 경우가 빈번합니다.
이번에 결제와 멤버십 관련 기능을 구현하는 업무를 맡았는데 멤버십의 가격이 변경된다던지 멤버십에 따른 기능 제한의 범위가 확대된다던지 등 여러 변경점이 생겼습니다.
이런 경우 만약 테스트 코드가 없다면 결국 해당 기능과 연결되어 보이는 모든 부분을 직접 확인하고 테스트해봐야 할 것입니다.
너무 비효율적인 일이죠 ㅎ…
테스트 코드를 작성하면 현재 작성하여 변경된 부분이 테스트가 성공하면 다른 메서드 및 클래스의 테스트 코드들을 실행하여 테스트 통과 여부를 확인하면 됩니다. 매번 일정한 값으로 일정한 테스트를 할 수 있다는 것이죠.

b) 예상하지 못한 오류에 대한 피드백을 위해

운영을 하다 보면 예상치 못한 오류가 나오기도 하죠.
QA에서 진행하지 못한 상황일 수도 있고 다른 쪽 기능이 변경되면서 데이터가 잘못 들어온다던가, 등 여러 상황이 있습니다.
서버단에선 테스트 코드가 있으면 해당 상황을 다시 재현하기도 훨씬 편합니다. 해당 테스트 코드에 에러 당시의 parameter값들을 그대로 넣어서 추측하기도 편합니다.
즉 테스트를 하기 더 편리하여지고 오류에 접근하기도 훨씬 간편합니다.
위의 a상황에서 언급한 다른 메서드의 기능이 변경의 영향점을 찾기에도 훨씬 편합니다.

a, b의 경우는 테스트 코드가 얼마나 잘 짜여있는지 어느 정도의 상황까지 테스트하는지 얼마나 세밀하고 정밀하게 짜여있는지에 영향을 많이 받습니다. 하지만 굉장한 큰 장점이죠

c) 좋은 설계로 작성되게끔 코드를 유도

테스트 커버리지라는 것이 있습니다. 로직들이 테스트로 인해 검증이 되냐 안되냐를 %로 확인할 수 있습니다.
테스트 커버리지를 높이려면 다양한 상황에 대한 테스트가 진행되어야 합니다.
이 경우 모든 기능을 한 메서드에 넣으면 추후 테스트할 때 굉장히 난처합니다.
어디서 오류가 낫는지 파악이 힘든 건 물론이고 무엇보다 테스트 시나리오를 작성할 때 굉장히 애를 먹습니다.
모든 분기점에 전부 걸리게끔 테스트를 진행해야 하는데 코드 파악도 힘든데 테스트 시나리오는 짜는 일에 엄청난 피로감이 들게 되죠.
더 테스트 하기 쉬운 구조에 대해서는 추후 포스팅 하겠습니다.

또한 TDD같이 테스트 코드를 먼저 짜고 진행을 하는 방법론을 적옹하여 개발할 경우엔 아마 처음 설계부터 메서드를 분리해서 하는 게 훨씬 편하기 때문에 oop의 원칙 중 SRP가 지키며 코딩을 하게 됩니다.

d) 기능 정의의 문서의 역할

테스트 코드는 어떤 기능을 수행하는 애플리케이션의 단위를 테스트하는 것입니다.
a메서드에 대한 테스트 코드를 작성한다고 가정을 해보겠습니다.
먼저 a메서드의 기능 정의를 해야 하고 a메서드가 실행 후 어떠한 상태로 return이 오는지 return이 없다면 어떠한 일을 하였는지를 검증해야 합니다.

이렇게 시나리오에 대한 a메서드의 기능과 데이터 검증이 테스트 코드에는 명시되어있습니다.

e) 실수를 줄여준다

이 부분은 너무 간단해 딱히 더 설명할 것이 없습니다. 말 그대로 테스트 코드를 작성하면 다양한 테스트를 하게 되는데 이 과정에서 놓치고 지나간 부분들을 생각하고 테스트하게 됩니다.

테스트 코드의 작성 규칙

그렇다면 좋은 테스트 코드를 작성하기위해 지켜야하는 규칙은 무엇일까요?

  • FAST
    • 테스트는 빨라야한다.
    • 테스트를 실행하는데 많은 시간적 비용을 지불하게 되면 테스를 자주 돌리지 않게 되는 효과가 나타난다.
    • 즉 초반에 문제를 찾고 해결 할 기회가 줄어든다.
  • Independent
    • 테스트는 독립적으로 시행된다
    • 테스트가 다른 테스트를 의존한다면 (테스트간의 순서가 중요한다던가) 테스트는 독립적으로 실행 된다 할수없다.
    • 의존하고있는 테스트가 실패시 다른 테스트들도 전부 실패함으로 원인을 진단하기 어려워진다.
    • 독립적으로 테스트를 짜야 결합이 더 잘 발견된다.
  • Repeatable
    • 테스트는 반복 가능해야 한다.
    • DB의 정보나 외부 api에 연동에 영향을 받아서는 안된다
    • DB의 정보가 필요할경우 맵퍼나 레파지토리를 모킹한다
    • 즉 순수 자바코드와 프로젝트내에서의 동작을 검증해야한다 (인터넷이 연결이 안되어있어도 돌아가야한다)
  • Self-Validating
    • 테스트는 자가 검증해야한다
    • 테스트코드에 로그를 찍어 확인하는 패턴은 금지
    • A메서드를 실행시 true라는 값이 나온다면 Assertion을 이용해 검증한다
    • 테스트 코드엔 성공/실패만 있어야한다
  • Timely
    • 테스트 코드는 적시에 작성한다
    • 기능의 완성된 이후 테스트코드를 끼워 맞추는것이 아닌 테스트코드로 상황과 기능의 정의를 내린후 로직을 작성한다

댓글남기기