TDD?
이번 포스팅에서는 TDD에 대해서 정리를 해보려고 한다.
우선 TDD란 Test Driven Development의 약어로 테스트 주도 개발을 의미한다.
즉, 테스트가 개발을 이끌어 나가는 형태의 개발론
이다.
이 TDD방식의 개발은 선 Test code 작성, 후 구현
을 의미하며, 총 3가지 (실패, 성공, 리팩토링)의 절차로 구성된다. 구체적인 내용에 대해서는 테스트 자동화(Automated Testing)와 테스트의 종류에 관련된 내용을 우선 정리하고 정리해보도록 하겠다.
우선 개발에서 테스트의 정의는 내가 작성한 코드가 잘 작동한다는 것을 검증하는 단계이다. 가장 기본적으로 만들어진 어플리케이션을 테스트하는 방법은 직접 마우스와 키보드를 사용해서 의도대로 잘 동작하는지 확인할 수 있다.
하지만 이렇게 모든 기능을 사람 손으로 하나하나 확인하는 것은 여간 번거로운 일이 아닐 수 없다.
그래서 테스트 코드라는 것을 작성해서 테스트를 자동화시켜준다. 테스트 자동화란 사람이 직접 어플리케이션의 동작을 확인하는 것이 아닌, 작성한 테스트 코드를 통해서 테스트 시스템이 자동으로 확인을 해주는 것을 말한다.
테스트 자동화(Automated Testing)
테스트 자동화의 장점
- 여러 사람들과 협업하여 작업을할때 각자가 작성한 코드에 문제가 있는지 빠르게 검사를 할 수 있다.
- 새로운 기능을 추가하는 작업의 경우, 기존의 기능들을 망가뜨리는 것을 사전에 방지할 수 있다.
- 테스트 코드를 적는다는 것은 개발할때 실제 발생할 수 있는 상황에 대하여 미리 정리해놓는 일련의 작업이기 때문에 미리 정리해놓고 그에 상응하는 코드를 작성하게 되면 필요한 사항들을 까먹지 않고 넣어줄 수 있다.
- Code Refactoring시에도 좋다. 일부 기능에 대한 코드를 리팩토링할때 기존에 이 기능에 대한 테스트 코드가 존재한다면 리팩토링한 후에도 동일한 동작을 하는지 검사하면 되기 때문에 검증하기가 쉽다.
테스트 종류
Unit Test
유닛 테스트는 어플리케이션의 각 기능들을 아주 작은 단위로 쪼개서 작성해서 테스트하는 것을 말한다. 큰 분류의 기능을 작은 단위로 쪼개서 테스트를 하게 되면 세부기능별로 잘 작동을 하는지 확인할 수 있다.
테스트시에 보통 한 개의 파일만 불러와서 진행한다.
ex) React에서의 Unit Test
- Component가 잘 rendering된다.
- Component의 특정 함수를 실행시키면 해당 상태가 원하는 형태로 바뀐다.
- Redux의 Action 생성 함수가 Action의 객체를 잘 만들어낸다.
- Redux의 Reducer에 상태와 Action 객체를 넣어서 호출하면 새로운 상태를 생성해준다.
Integrated Test
유닛 테스트가 각 기능의 세부 기능을 테스트했다면, 이제 통합 테스트를 통해서 전체적으로 테스트하는 어플리케이션이 잘 작동하는지 확인을 해야하는데 이때 하는 테스트가
통합 테스트(Integrated Test)
이다.
테스트시에 여러 파일들을 불러와서 진행된다.
ex) React에서의 Integrated Test
- 여러 Component들을 rendering하고 서로 상호작용을 하고 있다.
- DOM event를 발생시켰을때 UI에 원하는 변화가 잘 발생한다.
- Redux와 연동된 Container Component의 DOM에 특정 event를 발생시켰을때 기대하는 Action이 제대로 dispatch된다.
TDD의 3단계 절차
TDD방식으로 개발을 하기 위해서 우선 첫 번째 단계는 실패하는 테스트 케이스를 먼저 만드는 것
이다. 실패하는 테스트 케이스의 작성은 프로젝트 전체의 기능에 대한 테스트 코드가 아닌 당장 구현할 기능
하나씩 테스트 케이스를 작성하는 것을 말한다.
두 번째 단계는 성공하기 위한 코드작성
을 하는 단계이다. 첫 번째 단계에서 작성했던 실패하는 테스트 케이스들을 PASS시키기 위해서 실제 기능에 해당하는 코드를 작성
하는 단계이다.
세 번째 단계는 작성한 코드를 리팩토링
하는 단계이다. 두 번째 단계에서 구현한 코드에 중복되는 코드가 있거나, 혹은 코드를 좀 더 개선시킬 방법이 있다면 리팩토링을 진행한다. 리팩토링 후에 기존의 테스트 코드를 실행해서 문제없이 PASS가 되는지 확인을 한다. 이 단계까지 완료되었다면 다시 첫 번재 단계로 돌아가서 새롭게 추가해야되는 기능에 대한 실패하는 테스트 케이스를 작성하도록 한다.
TDD가 좋은 점
TDD로 개발을 진행하게 되면 테스트 케이스를 작성할때 기능을 작은 단위로 나눠서 작성을 하기 때문에 코드를 작성할때에도 코드가 너무 방대해지지 않고, 코드의 모듈화
가 자연스럽게 잘 이뤄지는 개발로 진행이 된다.
앞서 3 STEP에서 살펴보았듯이 실제 기능구현 이전에 테스트 코드를 작성하게 되면, 자연스럽게 Test Coverage가 높아진다. 이렇게 되면 향후에 코드를 리팩토링할때 그리고 유지보수를 할때에도 쉬워진다.
이처럼 TDD방식은 프로젝트의 환경을 좋게 구성하는데 일조를 한다.
요구사항 => 테스트 코드 => 구현 => 테스트 코드 실행
요구사항에 맞춰서 기능을 세분화해서 테스트 코드를 작성하기 때문에 실수로 요구사항을 빼먹거나 하는 실수를 사전에 방지할 수 있다.