위코드에서 공부하며 정리한 내용입니다.
소프트웨어를 배포하기 전 동작여부를 검증합니다. 테스트 종류는 크게 유닛 테스트, 통합 테스트, 인수 테스트로 나눌 수 있습니다. 보통 QA 과정에서 자동화로 테스트를 진행합니다. 유닛 테스트는 각 함수 및 클래스 단위로 진행해서 전체의 70% 정도를 차지합니다. 통합 테스트는 모듈들을 조합해서 테스트를 구성하므로 20% 정도, 인수 테스트는 통합테스트와 비슷하지만 실제 환경을 가정하고 테스트해서 10% 정도입니다. 유닛과 통합 테스트가 빌드의 올바른 수행에 집중한다면, 인수 테스트는 빌드된 소프트웨어가 정상적으로 작동하는가에 초점을 맞춥니다.
단위, 유닛 테스트는 소프트웨어를 단위별로 분리해 테스트하는 방법입니다. 주로 함수와 클래스 단위로 나누는데 모든 개발의 단위가 나눠져 있지 않기 때문에 나누는 과정에서 개발 품질을 높일 수 있습니다. 이를 모듈화라고 하고, 단위 테스트는 모듈별로 독립적으로 테스트해 다른 모듈에 영향을 주지 않고 안전하게 테스트를 진행합니다.
단위 테스트를 모아서 테스트하는 것을 의미합니다. 계산기의 더하기만 테스트하면 유닛 테스트지만 더하기 빼기를 동시에 테스트한다면 상향식 통합 테스트입니다. 반면 모듈이 있는 것을 가정하고 테스트하는 것을 하향식 통합 테스트라고 합니다.
통합 테스트에서 더 나아가 실제 환경처럼 맞추어 테스트하는 방법입니다. 알파 테스트, 베타 테스트 등이 있는데, 알파 테스트는 폐쇄적인 환경에서 개발자 통제 하에 테스트를 진행하고 베타 테스트는 개방적인 환경에서 비교적 자유롭게 테스트를 진행합니다.
테스트가 코드를 커버하는 정도를 나타냅니다. 커버리지는 함수(function), 구문(statement), 조건(condition), 분기(branch)로 분류됩니다. 함수가 실행되지 않으면 다른 커버리지 또한 측정할 수 없으므로 함수 커버리지는 테스트들을 포괄하는 개념입니다.
함수 커버리지(%) = 실행된 함수 개수 / 총 함수 개수 * 100
구문 커버리지는 코드의 하나의 구문이 실행되는 정도를 의미하며, js 에서 하나의 구문은 보통 세미 콜론(;)으로 구분합니다.
구문 커버리지(%) = 실행된 구문 수 / 전체 구문 수 * 100
조건 커버리지는 if 조건들이 true 와 false 를 가지는 정도를 의미합니다.
조건 커버리지(%) = 각 조건마다 true or false 한번의 개수 / (전체 조건 수 ^ 2) * 100
분기 커버리지는 조건으로 나뉘는 실행 경로를 의미합니다. 조건이 많아지면 분기 커버리지 전체 양이 늘어나므로 테스트할 부분이 많아집니다.
분기 커버리지(%) = 실행된 분기 수 / 총 분기의 개수 * 100
소프트웨어 테스트 역사는 크게 5가지로 나뉩니다. 디버깅 지향, 증명 지향, 파괴 지향, 평가 지향, 예방 지향 시대로 구분합니다. 디버깅 지향 시대 때는 테스팅의 주목적이 버그 제거 였고, 증명 지향 시대 때는 소프트웨어의 요구사항을 포함하기 시작했고(여전히 디버깅 목적이 남은 채로), 파괴 지향 시대 때는 오류를 찾는데 초점을 맞추어, 오류가 발생하면 오류를 찾고 수정하는 디버깅 작업으로 나뉘게 되었습니다. 평가 지향 시대 때는 테스팅이 소프트웨어 개발 생명 주기에 포함되어 테스트의 중요성이 부각되었고, 예방 지향 시대 때는 소프트웨어 개발 전반적인 부분의 문제를 미리 찾기 위해 테스팅을 진행하게 되었습니다.
TDD 라는 개발 방법론이 등장했습니다. 기존 Waterfall 방식이 설계 - 개발 - 테스트 코드 작성 순으로 진행되었다면 TDD 는 테스트 코드 작성 - 개발 - 리팩토링 방식으로 진행합니다. TDD 는 테스트 주도 개발이라고 부르며 테스트 코드가 설계의 역할을 합니다. 테스트 코드를 먼저 작성해 설계한 후, 하드 코딩하여 빠르게 기능을 구현하고 리팩토링해 성능 및 안정성을 높입니다.
소프트웨어의 품질을 보장하기 위해 테스트 합니다. 각종 결함 및 버그를 찾아 해결하고, 기존 명세대로 개발되었는지 테스트하고 인수 테스트를 통해 사용자의 요구사항을 충족했는지도 확인할 수 있습니다.
기능 추가, 버그 제거, 리팩토링을 하며 개발자가 실수를 한다면 기존 자동화 테스트 코드 통과 여부로 실수를 잡아낼 수 있습니다. 유지보수 할 수 없는 소프트웨어는 퇴사자의 소프트웨어가 아니라 테스트 코드가 없는 소프트웨어라는 말이 있습니다.
함수에 입력을 직접 넣어서 결과를 확인하거나 버튼을 눌러서 테스트하는 방법입니다. 테스트를 계획하고 수행하고 결과는 내는 과정이 있으며 개발중이거나 배포 직전 QA 때 진행합니다. 주로 사용성을 검증할 수 있는 UI, UX 테스트에 수행합니다. 수동 테스트는 누구나 직관적으로 쉽게 테스트를 실행할 수 있지만 실행 속도가 느리고 부정확할 수 있습니다.
시스템 테스트를 최대한 자동화해서 휴먼 에러를 줄이고, 정확하게 반복적으로 빠지는 부분 없이 실행되도록 하면 개발팀의 생산성을 높이고 시스템을 안정적으로 운영할 수 있습니다. 인수 테스트는 프론트엔드부터 백엔드까지 모든 시스템을 실행시키고 연결해 놓은 상태에서 진행하는 테스트라 설정하는 시간도 오래 걸리고 실행 속도도 느려 자동화하기 가장 까다롭습니다. 그래서 테스트 전략 중 가낭 낮은 비율을 차지합니다.
단위 테스트는 개발자가 테스트 코드를 작성해 언제든 실행할 수 있고 실행 속도도 빨라서 100% 자동화가 가능합니다. 자동화와 함께 디버깅을 도와주므로 소프트웨어를 빌드할 때 사전에 오류를 찾아내 수정할 수 있고, 빌드 전 테스트를 자동으로 수행하는 스크립트를 통해 자동화를 할 수 있으며 빌드 혹은 컴파일 하기 전, 원격 저장소에 코드가 올라가지 전에 검사해 안정적으로 코드를 관리할 수 있습니다.