44주 차가 되어서야 적는 43주 차 WIL이다. 한 게 없어서 안 적은 것은 아니고, nestJS로 백엔드를 빌드하는 과정이 처음이기도 하고 테스트 코드를 작성하는 것은 더 처음이라 사소한 선택에 있어서도 많은 고민이 있었고, 관련된 레퍼런스들을 찾아 보고 정리하다 보니 일주일이 훌쩍 가버렸다. 그러면서 정체된 작업을 어떻게 해서든지 앞으로 밀고 가려고 잡고 있다 보니 WIL이 좀 밀렸다.
당연히 처음이라서 오래 걸리는 건 알지만, TS가 생산성을 올려주는 건지 원론적인 의문이 생겼다ㅋㅋㅋ 더 공부하고 경험이 쌓인다면 이런 의문을 한 나를 어리석게 여기겠지.. 그래서 오늘은 그간 정리한 레퍼런스 중 하나를 여기에 옮겨볼까 한다.
테스트 코드를 작성하기 위해서 이런 저런 문서들을 찾다 보니까 화이트 박스 테스트, 블랙 박스 테스트라는 용어들이 등장했다. 그래서 이게 뭔지를 찾아보다 보니까 기존에 E2E 테스트, Unit 테스트의 이분법적인 분류가 아닌 조금 더 큰 틀에서의 테스트 분류에 대해서 접하게 됐다. 단위 테스트, 통합 테스트, 인수 테스트가 그것이다. 오늘은 해당 내용에 대해서 정리를 해볼까 한다.
단위 테스트(Unit Test)는 하나의 클래스나 함수의 범주에서 작은 단위의 기능을 검증하는 테스트다. 테스트 대상을 어느 정도의 단위로 하라고 명시된 것은 없지만 단위의 크기가 작으면 작을수록 복잡성은 낮아지고 디버깅도 쉬워진다. 요즘 많이 사용되는 Test Driven Development에서 하는 'Test'도 이 단위 테스트를 의미한다. 해당 부분만 독립적으로 테스트를 하기 때문에 어떤 코드의 문제가 있는지 신속히 확인할 수 있다.
하지만 하나의 어플리케이션은 하나의 클래스나 함수로 작동되는 경우는 거의 없다고 볼 수 있다. 즉, 여러 클래스와 함수가 함께 맞물려 작동되는 경우가 대부분인데 이런 부분에서 단위 테스트의 불편함이 있다. 예를 들어 다른 모듈과 객체나 메시지, 데이터를 주고 받아야 한다면 이를 테스트 하기 위해선 동일한 형식의 가짜 객체, 데이터를 준비해야 하는데, 이걸 stub이라고 한다.
이런 부분에서 단위 테스트는 소프트웨어 내부 구조나 구현 방법을 고려하여 개발자 관점에서 테스트를 진행한다. 그러므로 단위 테스트는 소프트웨어 내부 코드에 관련한 지식을 반드시 알고 있어야 하는 화이트 박스 테스트이다.
소프트웨어 혹은 제품의 내부 구조나 동작을 세밀하게 검사하는 테스트 방식으로 외부에서 요구사항에 따른 예상 결괏값을 테스트하는 것과는 다르게 내부 소스 코드를 테스트하는 기법으로 사용자가 들여다 볼 수 없는 구간의 코드 단위를 테스트 한다.
즉, 개발자가 소프트웨어 또는 컴포넌트 등의 로직에 대한 테스트를 수행하기 위해 설계 단계에서 요구된 사항을 확인하는 개발자 관점의 단위 테스팅 기법이다.
소프트웨어의 내부 구조나 작동 원리를 모르는 상태에서 소프트웨어의 동작을 검사하는 방법이다. 검사 진행에 있어서 해당 소프트웨어의 내부 코드 및 구조에 대한 정보는 필요하지 않고 요구 사항 검사를 위해 공개된 설계도 등의 대외적으로 공개된 사항들을 통해 검사를 진행한다.
즉, 정리하면 개발자 입장이 아닌 사용자 입장에서 소프트웨어 혹은 제품에 대한 요구사항과 결과물이 일치하는지 확인하기 위한 테스트 기법이다.
통합 테스트(Integration Test)는 앞서 살펴 본 단위 테스트 보다 더 큰 규모의 작동을 테스트 하기 위해 여러 모듈들을 모아 개발자의 의도대로 잘 맞물려 돌아가는지 확인하기 위한 테스트이다. 이 과정에서는 단위 테스트가 끝난 모듈을 통합하는 과정에서 생길 오류를 찾을 수 있다. 예를 들어서 통합 테스트 환경에서는 싱글 코어 CPU에서는 잘 실행되나 쿼드 코어 CPU에서는 잘 실행되지 않을 수 있고, 외부 라이브러리와 같이 개발자가 직접 변경하기 어려운 부분까지 통합해서 테스트를 하면 또 문제가 생길 수 있다. 이런 부분 때문에 해당 모듈이 단위 테스트를 모두 통과했다고 통합 테스트에서 문제가 안 생긴다는 보장은 절대 없다.
통합 테스트 또한 단점이 있는데, 단위 테스트 보다 많은 코드들을 통합해서 테스트를 하는 것이다 보니 개별 코드에 대한 신뢰성이 떨어질 수 있고, 에러가 발생했을 때 어떤 코드가 어떤 코드의 영향을 받아서 에러가 발생했는지 명확히 파악하기가 힘들 수 있다. 이런 부분은 유지 보수의 난이도를 높인다.
인수 테스트(Acceptance Test)는 실제 사용자 환경에서, 사용자의 입장으로 하는 테스트이다. 개발 완료 단계에서 시스템의 인수를 위해 기능적/비기능적 요구사항을 사용자의 입장에서 테스트를 하고 개발이 완료됐음을 증명한다.
테스트는 시나리오를 바탕으로 진행한다. 이 시나리오는 개발자가 직접 작성할 수도 있지만, 다른 의사소통 집단에서 받아서 하는 경우가 보통이다. 이처럼 정해진 시나리오에 따라 어플리케이션이 잘 작동하는지를 확인하기 때문에 통합 테스트와는 분류가 다르다. 시나리오는 주로 누가, 어떤 목적으로, 무엇을 하는가를 중점으로 작성이 되는데, 개발에서 이런 부분은 API를 통해서 잘 드러난다. 그래서 인수 테스트는 주로 API를 확인하는 방식으로 이루어 진다. 실제 사용자 관점에서 테스트를 하기 때문에 E2E 형식으로 진행한다.
소프트웨어를 인수할 때는 내부의 코드의 품질 보다 시나리오에 따라 잘 작동하는지를 보는 블랙 박스 테스트이다.
참고자료
https://tecoble.techcourse.co.kr/post/2021-05-25-unit-test-vs-integration-test-vs-acceptance-test/
https://mangkyu.tistory.com/143