테스트의 단어에는 큰 뜻을 내포하고 있지 않다.
이미 우린 수없이 많은 테스트를 쓰고 있으며, 또한 주변에도 늘 존재한다
'어떠한 대상에 대해 일정한 기준을 정한 뒤, 그 대상이 정해진 기준에 부합하는지 부합하지 못하는지를 검증하는 과정' 이라 설명할 수 있다.
매우 중요한 부분이다 테스트를 하지 않으면 어떤 대상에 대한 검증이 정상적으로 이루어지지 않아 잘못된 결과에 직면할 수 있다.
대상이 무엇이 되었든 테스트를 제대로 잘 거쳐 테스트 대상이 검증 과정에 잘 통과하게 만들어 최대한 나은 결과를 얻기 위해서 이다.
하지만 모든 테스트를 통과해서 더 '최대한 나은 결과'라 해서 모든 테스트가 100퍼센트 완벽하게 이루어 질 순 없다.
그러면 완벽하지 않은 테스트에 대해 진행을 해야하나?
물론 해야한다, 전혀 테스트를 진행하지 않은 결과와 일말의 테스트를 진행한 결과는 완성도와 결과에서 큰 차이가 생기며, 테스트를 진행한 결과는 문제를 해결할 가능성이 월등히 높으니깐
단위 테스트는 컴퓨터 프로그래밍에서 소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차이다.
즉, 모든 함수와 메소드에 대한 테스트 케이스를 작성하는 절차를 말한다.
출처 위키피디아
단위 테스트는 우리가 작성한 코드가 의도한 대로 작동하는지 검증하기 위한 절차로 문제를 방지하는 기능도 있지만,
부수적으로 코드 변경에 의한 사이드 이펙트를 최대한 줄일 수 있는 예방책이 되기도 한다.
그리고 서비스 요구사항 변경이나 리팩토링으로 인해 코드 수정이 필요한 상황에서 더 유연하고 안정적인 대응을 할 수 있게 되고, 테스트 코드를 작성하는 과정에서 자연스럽게 코드의 모듈화를 고민하게 되는 등의 부수적 이점도 가지고 있다.
단위 테스트는 매우 간단하고 명확하며 빠르게 실행된다는 특징이 있다.
쉽게 풀면, 하나의 함수에 대해 하나 이상의 테스트가 존재할 수 있고, 각각의 조건에 대한 유효성을 검증한다
이렇게 작성된 단위 테스트가 많을수록 해당 로직에 대한 신뢰도가 높아질 수 있다.
또한, 작게 쪼개진 단위 테스트는 해당 로직이 어떤 역할을 하는지 쉽게 파악할 수 있다는 장점이 있다.
슬라이스 테스트는 애플리케이션을 특정 계층으로 쪼개어 하는 테스트를 말한다
어떻게 보면 단위 테스트와 비슷하다 슬라이스 테스트를 잘게 쪼개면 말이다
하지만 단위 테스트보단 조금 더 넓은 범위를 테스트하는 개념이다
또한 슬라이스 테스트는 해당 계층에서 HTTP 요청이 필요하고, 외부 서비스가 연동되기도 하며 특히나 데이터 액세스 계층의 경우 여전히 DB와 연동되어 있기 때문에 슬라이스 테스트는 단위 테스트보단 말 그대로 계층별로 쪼개어 테스트 한다는 의미를 갖는다.
중형 테스트에 속하는 통합 테스트는 서로 다른 모듈 혹은 클래스 간의 상혹작용의 유효성을 검사하는 테스트이다.
이러한 통합 테스트가 필요한 이유는 각각의 단위 테스트가 검증되었다 해도, 모듈 간 인터페이스 및 데이터의 흐름이 의도한 대로 제대로 동작하지 않는 경우가 있기때문에 조금 더 넓은 범위에서 추가적인 테스트가 필요하다
그리고 통합 테스트는 각 모듈에 대한 설정 또는 테스트를 하기 위해 사전 조건이 필요한 경우도 있기 때문에,
단위 테스트보다 테스트 코드를 작성하기가 복잡하다.
하지만 단위 테스트보다 더 넓은 범위의 종속성까지 테스트함으로써 단위 테스트보다 좀 더 유의미한 테스트가 되는 경우가 많다고 한다.
기능 테스트는 E2E Test || Browser Test 라고 불리며 모두 같은 의미이다.
기능 테스트는 어떤 어플리케이션이 제대로 동작하는지 완전한 기능을 테스트하는 것을 말한다
예를 들자면, 어떤 웹 어플리케이션을 기능 테스트한다고 가정해보면 브라우저 자동화 도구를 사용해 특정한 페이지를 클릭한다던가 하는 것이 기능 테스트라 할 수 있다.
기능 테스트는 유닛 테스트와 비교하자면 작성하기가 매우 어렵고 높은 복장성을 갖고 있어 시간이 많이 걸린다
그래서 유닛테스트와 다르게 세밀하게 나눠서 하면 좋지 않다.
대신 사용자와 앱의 상호작용을 테스트하고 싶을 때 유용하다
'Clean Code' 저자인 Bob Martin이 처음 제시한 규칙이다
유닛 테스트는 빠르게 실행되고 빠르게 결과를 알아야 한다
그러므로 하는 일의 단위가 최대한 작아야한다.
또한 빠른 테스트를 하기 위해서 실제 서버나 데이터베이스를 이용하지 않고, 가짜 데이터(모의 데이터)를 생성해
테스트를 진행해야 한다.
만약 데이터를 최신 날짜순으로 정렬하여 가장 최근 데이터 5개를 가져오는 것을 테스트하려고 하는데
실제 서버에 문제가 생겨 데이터가 느리게 받아져 오거나 데이터가 오지 않는 경우엔 테스트를 진행하기가 어려울것이다.
그러니 가짜 데이터로 실제 테스트를 하고싶은 부분만 잘라 진행 하는 것이다.
유닛 테스트는 그 자체만으로 실행되어야 한다
즉, 독립적이어야하며 다른 테스트에 의존하거나 영향을 주어선 안된다.
만약, 떠그 라는 이름을 가지고 있는 데이터가 있다고 가정해보자
이 데이터는 그 전 테스트에서 이름이 잘 바뀌는지 테스트를 했다 (떠그 -> 라이프)
그리고 이름에 '그' 라는 단어가 들어가는지 테스트를 하려고 하는데 만약 그 전에 테스트에 의존한다면
그 전 테스트에서 어떻게 이름을 바꿨는지에 따라 결과가 바뀔것이다.
그러니 모든 테스트에는 서로 영향을 주면 안된다.
유닛 테스트는 반복이 가능해야 한다
테스트를 어디서 어떻게 몇 번을 진행하든 똑같은 결과가 나와야 한다.
예를 들어, 어떤 숫자에 5를 곱하는 테스트를 한다고 가정하면
항상 5를 곱한 숫자가 나와야한다
이 원칙은 의존성과도 관계가 깊다, 어떤 데이터가 영향을 미친다면 당연하게도 동일한 결과가 나오지 않을것이다
유닛 테스트는 자체 검증이 가능해야한다.
테스트 자체로 통과인지 실패인지 결과가 나와야 하며 이것은 자동적으로 이루어져야 한다.
즉, 통과인지 실패인지 두 가지 뿐, 결과가 애매한 상황이 없어야 한다는 것이다
또한 자동적으로 이뤄진다는건 코드를 작성하는 사람이 출력이나 로그를 통해서 수동적으로
결과를 확인하는 것이 아닌 그 테스트 자체적으로 결과가 나와야한다.
유닛 테스트는 철저하고 적절한 때 작성되어야 한다
철저하다는 것은 모든 데이터를 검사해야 하므로 최소에서 최대까지 범위를 포함하고
역할에 따라 바뀌는 데이터 사용자, 관리자일때 모두 테스트가 가능해야 하며
어떤 케이스가 실패(예외나 오류)하는지도 테스트 해야한다
또한, 유닛 테스트는 실제 코드를 작성하기 바로 전에 작성해야 한다.