Unit Test란 무엇인가?
테스트 자동화의 중요성
테스트는 버그가 있음을 보여줄 뿐, 버그가 없음을 보여줄 수는 없다.
-에츠허르 비버 데이크스트라
테스트는 버그를 잡아내기 위해 필수적으로 필요한 장치입니다. 안정적으로 수익이 창출되는 서비스를 위해서 테스트는 꼭 필요한 과정이죠. 초기의 테스트는 Manual Test라는 이름으로 사람이 직접 진행했습니다. 그러나 테스트의 실행 속도가 느리고, 인력 소모가 많습니다. 그래서 불안정하고 비용도 많이 들죠. 이러한 이유로 규모가 큰 회사와 서비스는 Manual Test를 진행하기 어렵죠. 이로서 다양한 시스템 전략들이 등장합니다. 먼저 대표적인 테스트 전략들을 살펴보죠.
시스템 테스트 전략 3가지
- UI Test: End-To-End testing이라고 불리며 UI를 하나 하나 보면서 체크해 나간다. 자주 진행하지는 않지만 실재 사용자의 경험과 동일하기 때문에 배포 전에 꼭 한번 진행해준다. 프론트 엔드 단에선 이 테스트의 비중이 가장 높고 cypress 같은 툴을 통해 자동화도 가능하다.(10%)
- Integration Test: 포스트맨, mock Data 등으로 직접 요청을 해나가면서 백앤드와 프론트가 따로 데이터의 구조를 확인하며 테스트를 진행함. 포스트 맨의 한계로 100% 자동화를 진행하기는 어려움(20%)
- Unit Test: 전체 테스트의 70%를 차지하는 중요한 테스트. 코드만 작성해 두면 모든 엔드포인트를 돌면서 테스트하기 때문에 자동화를 진행하기 쉽니다.
Unit Test
테스트 할 수 있는 가장 작은 단위를 테스트하는 코드를 작성해서 테스트하는 것을 의미합니다. 가장 작은 단위는 대체로 함수를 의미하죠. 백엔드의 경우 함수로 구성된 ‘뷰’, 프론트도 마찬가지로 함수를 기준으로 테스트가 진행됩니다. 테스트는 라이브러리에서 테스트 코드를 이용해 실행이 가능합니다.
Unit Test 용어
- TestCase: unittest Feamework의 테스트 조직의 기본 단위. 성공 케이스, 실패 케이스, 예외 케이스 등으로 구분해서 관리하기도 합니다.
- Fixture: 테스트를 진행할 때 필요한 테스트용 데이터 혹은 설정 등을 이야기 합니다. 주로 테스트가 실행되기 전이나 후에 생깁니다. 테스트가 진행되기 전에 생성되고 테스트 후에는 지워지면서 코드가 깨끗한 상태로 유지해준다.
- Assertion: 테스트가 제대로 됐는지 확인하는 부분. 정확한 값이 들어오는지 보는 단계입니다.
가장 좋은 테스트 케이스는 성공 케이스(1), 실패 케이스(-1), 예외 처리 케이스(0)를 정확히 반환해 주는지 확인합니다.
유닛 테스트 구현에 지켜야 하는 일반적인 원칙들
- 테스트 유닛은 가장 작은 단위에 집중해서 만듭니다(함수 단위로 테스트 진행)
- 각 테스트 유닛은 반드시 독립적이어야 합니다.
- 테스트가 빠르게 돌 수 있도록 만들기 위해 노력해야 합니다.(배포 전까지 모든 요소의 검사를 위해선 빠른 테스트가 중요합니다.)
- 지금 사용하는 툴이 개별 테스트나 테스트 케이스를 어떻게 수행하는지 배우셔야 합니다.
- 그날의 코딩을 시작하기 전에 항상 풀 테스트 슈트를 돌려야 한다.(pull을 받고 나서 test를 통해 기능을 확인한다.)
- 모두가 공유하는 저장소에 코드를 집어넣기 전에 자동으로 무든 테스트를 수행하도록 하는 훅을 구현하는게 좋습니다.
- 코드를 디버깅 할 때 가장 먼저 시작할 일은 버그를 찝어내는 새로운 테스트를 작성하는 것입니다.
- 테스트 함수에는 길고 서술적인 이름을 사용해야 합니다.(ex. test_square_of_number_2())
- 테스트 코드의 또다른 사용 방법은 새로운 개발자들을 위한 안내서로 쓰일 수 있습니다.