TIL 클린코드 - 9장. 단위 테스트
TIL (Today I Learned)ㅍ
2022.05.07
오늘 읽은 범위
9장. 단위 테스트
책에서 기억하고 싶은 내용을 써보세요.
- TDD 법칙 세가지
- 첫째 법칙: 실패하는 단위 테스트를 작성할 때 까지 실제 코드를 작성하지 않는다.
- 둘째 법칙: 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
- 셋째 법칙: 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
- 실제 코드와 맞먹을 정도로 방대한 테스트 코드는 심각한 관리 문제를 유발하기도 한다.
- 깨끗한 테스트 코드 유지하기
- 지저분한 테스트 코드를 내놓으나 테스트를 안 하나 오십보 백보라는, 아니 오히려 더 못하다는 사실을 깨닫지 못했다.
- 새 버전을 출시할 때마다 팀이 테스트 케이스를 유지하고 보수하는 비용도 늘어난다. 점차 테스트 코드는 개발자 사이에서 가장 큰 불만으로 자리잡는다.
- 하지만 테스트 슈트가 없으면 시스템 이쪽을 수정해도 저쪽이 안전하다는 사실을 검증하지 못한다.
- 코드에 유연성, 유지보수성, 재사용성을 제공하는 버팀목이 바로 단위테스트다.
- 테스트 커버리지가 높을수록 공포는 줄어든다.
- 깨끗한 테스트 코드
- 깨끗한 테스트 코드를 만들려면 세 가지가 필요하다. 가독성, 가독성, 가독성.
- 첫 부분은 테스트 자료를 만든다. 두 번째 부분은 테스트 자료를 조작하며, 세 번째 부분은 조작한 결과가 올바른지 확인한다.
- 이중 표준 - 테스트 API 코드에 적용하는 표준은 실제 코드에 적용하는 표준과 확실히 다르다. 단순하고, 간결하고, 표현력이 풍부해야 하지만, 실제 코드만큼 효율적일 필요는 없다.
테스트 당 assert 하나
- assert문이 단 하나인 함수는 결론이 하나라서 코드를 이해하기 쉽고 빠르다.
- 하지만 특정 케이스에는 assert 문을 하나로 병합하는 방식이 불합리하기 때문에 테스트를 두 개로 쪼개 각자가 assert를 수행하면 된다.
// 출력이 XML이다. public void testGetPageHierarchyAsXml() throws Exception { givenPages("PageOne", "PageOne.ChildOne", "PageTwo"); whenRequestIsIssued("root", "type:pages"); thenResponseShouldBeXML(); } // 특정 문자열을 포함한다. public void testGetPageHierarchyHasRightTags() throws Exception { givenPages("PageOne", "PageOne.ChildOne", "PageTwo"); whenRequestIsIssued("root", "type:pages"); thenResponseShouldContain( "<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>"); ); }- 함수 이름은 given-when-then 관례를 잘 사용하자.
- 중복 제거하는 법
- given/when 부분을 부모 클래스에 두고 then 부분을 자식 클래스에 두면 된다. 아니면 독자적인 테스트 클래스를 만들어 @Before 함수에 given/when 부분을 넣고 @Test 함수에 then 부분을 넣어도 된다.
- 하지만 모두가 배보다 배꼽이 더 크다. 이것 저것 감안해 보면 assert 문을 여럿 사용하는 편이 좋다고 생각한다.
- 가장 좋은 규칙은
개념 당 assert 문 수를 최소로 줄여라와테스트 함수 하나는 개념 하나만 테스트하라
- F.I.R.S.T
- Fast: 테스트는 빨리 돌아야 한다.
- Independent: 각 테스트는 서로 의존하면 안된다. 각 테스트는 독립적으로 그리고 어떤 순서로 실행해도 괜찮아야 한다.
- Repeatable: 테스트는 어떤 환경에서도 반복 가능해야 한다. 테스트가 돌아가지 않는 환경이 하나라도 있다면 테스트가 실패한 이유를 둘러댈 변명이 생긴다.
- Self-Validating: 테스트는 bool값으로 결과를 내야 한다. 테스트가 스스로 성공과 실패를 가늠하지 않는다면 판단은 주관적으로 되며 지루한 수작업 평가가 필요하게 된다.
- Timely: 테스트는 적시에 작성해야 한다. 단위 테스트는 테스트 하려는 실제 코드를 구현하기 직전에 구현한다. 어떤 실제 코드는 테스트하기 너무 어렵다고 판명날지 모른다. 테스트가 불가능하도록 실제 코드를 설계할지도 모른다.
오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요
- 최근에 진행한 프로젝트에서 특정 페이지에 기능을 추가한적이 있었다. 아주 간단한 기능이라 버그가 없을 거라 생각하고 배포했는데, 기존에 잘 됐던 기능이 새로운 기능 추가로 인한 코드 수정 때문에 잘 작동하지 않아서 문제가 되었던 경험이 있다. 해당 페이지는 테스트 코드가 없었는데 테스트 케이스를 작성했다면 해당 버그를 사전에 잡을 수 있었을텐데..라며 아쉬워했다. 그래서 책을 읽으면서
테스트 슈트가 없으면 시스템 이쪽을 수정해도 저쪽이 안전하다는 사실을 검증하지 못한다.라는 문구에 격공을 했다. - 테스트 코드 작성법이 익숙하지 않기도 하고 기능 구현에 급급해서 테스트 코드를 많이 작성하지 못한다. 그래서 전에는 실제 코드를 다 짜놓고 테스트 코드를 짜면서 굳이 실제 코드전에 짜야할 이유가 있을까? 하고 생각한 적이 있는데, 깨끗한 테스트 다섯가지 규칙을 이번에 읽고 이유를 알게 되었다. 적시에 작성하지 않으면 테스트가 불가능하도록 실제코드를 설계할 가능성이 커지고 그러면 테스트 코드를 작성하지 않을 가능성도 높아지기 때문이다. 테스트 코드 작성법을 더 능숙하게 익혀서 실제 기능 구현 전에 능숙하게 짜보고 싶다.
더 공부한 내용