단위 테스트가 뭔데

iqpizza6349·2022년 6월 3일
3

Spring

목록 보기
1/6
post-thumbnail

단위 테스트(Unit Test)? 어디서 많이 들어봤는 데?

단위 테스트는 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트이다.

* 애플리케이션에서 작동하는 하나의 기능 또는 메소드로 이해할 수 있다.

예를 들면 웹 애플리케이션에서 로그인 메소드에 대한 독립적인 테스트가 1개의 단위 테스트가 될 수 있다.
즉, 단위 테스트는 애플리케이션을 구성하는 하나의 기능을 올바르게 작동하는 지 독립적으로 테스트하는 것으로, "어떤 기능이 실행되면 어떤 결과가 나온다." 정도로 테스트를 진행한다.

그럼, 통합 테스트(Integration Test)는 뭔데?

통합 테스트는 모듈을 통합하는 과정에서 모듈 간의 호환성을 확인하기 위해 수행하는 테스트이다.
일반적으로 애플리케이션은 여러 개의 모듈들로 구성되어 있고, 모듈들 끼리 메시지를 주고 받으면서 (함수 호출) 기능을 수행한다.

그렇기에 통합된 모듈들이 올바르게 연계되어 동작하는 지 검증이 필요한데, 이러한 목적으로 진행되는 테스트가 통합 테스트이다.
즉, 통합 테스트는 독립적인 기능에 대한 테스트가 아닌 웹 페이지로부터 API를 호출하여 올바르게 동작하는 지를 확인하는 것이다.

단위 테스트가 외 필요해?

외않되

통합 테스트는 실제 여러 컴포넌트들 간의 상호작용을 테스트하는 것이 때문에 캐시나 데이터베이스 등 다른 컴포넌트들과 실제 연결을 해야하고, 시스템을 구성하는 컴포넌트들이 많아질 수 있기때문에 테스트를 위한 비용(시간)이 상당히 커진다.

반면 단위 테스트는 해당 부분을 독립적으로 테스트하기 때문에 어떤 코드를 리펙토링한다 하더라도 빠르게 문제 여부를 확인할 수 있다. 단위 테스트의 필요성은 다음과 같다.

  • 테스팅에 대한 시간과 비용을 절감할 수 있다.
  • 새로운 기능 추가 시 수시로 빠르게 테스트할 수 있다.
  • 리펙토링 시 안정성을 확보할 수 있다.
  • 코드에 대한 문서가 될 수 있다.

작성된 테스트 코드를 수시로 빠르게 돌리면서 문제를 파악 및 해결할 수 있다.

모든 것에는 장단점이 있기 마련이지

단위 테스트의 장점과 필요성을 알아봤으니, 단점 역시 알아본다.
앞서 설명했듯이 단위 테스트는 독립적이다. 독립적으로 객체 자체적으로 모든 일을 처리한다면 문제가 발생하지 않겠지만, 일반적으로 애플리케이션에서는 1개의 기능을 처리하기 위해 다른 객체들과 메시지(함수 호출)를 주고 받아야한다.
하지만 단위 테스트는 독립적이기에 다른 객체에 메시지를 주고 받는 경우에 문제가 발생한다.

그런데 짜잔, '절대'라는 건 없군요


위 같은 단점이 있다하더라도 다른 객체 대신에 가짜 객체(Mock Object)를 주입하여 어떤 결과를 반환하라고 정해진 답변을 준비시켜야하는 데, 이를 stub이라고 한다.
예를 들어 데이터베이스에

select * from users where id = 1

위와 같은 sql를 보낼 때 Mock Database를 주입하여 select 처리 시, 반드시 id = 1에 해당하는 객체를 반환하는 것을 stub이라고 한다.

좋은 단위 테스트의 특징

요구 사항은 끊임없이 변경되고, 그에 맞는 코드를 구현해야한다. 하지만 코드를 변경한다는 것은 잠재적인 버그가 발생할 수 있음을 의미한다. 좋은 테스트 코드가 있다면, 변경된 코드를 검증함으로써 이를 해결할 수 있다. 또한 실제 코드가 변경되면 테스트 코드 역시 변경이 필요할 수 있는 데, 이러한 이유로 테스트 코드를 가독성있게 작성할 필요가 있다.
1. 1개의 테스트 함수에 대해 assert를 최소화하라
2. 1개의 테스트 함수는 1가지 개념만 테스트하라

또한 좋고 깔끔한 테스트 코드는 FIRST라는 5가지 규칙을 따라야한다.

  • Fast: 테스트는 빠르게 동작하여 자주 시연할 수 있어야한다.
  • Independent: 각각의 테스트는 독립적이며, 서로 의존하여서는 안된다.
  • Repeatable: 어느 환경에서도 반복 가능해야한다.
  • Self-Validating: 테스트는 성공 또는 실패로 결과를 내어 자체적으로 검증해야한다.
  • Timely: 테스트는 적시에 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현해야한다.
profile
coffee.drinkUntilEmpty();

0개의 댓글