LoginGustBookCategories
TDD

Principles of Test Code

thumbnailCreatehb21·2022년 01월 14일 02:47

https://images.unsplash.com/photo-1577760258779-e787a1733016?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NHx8dGVzdGluZ3xlbnwwfHwwfHw%3D&auto=format&fit=crop&w=800&q=60


Secrets of Test Code

  1. 한번 작성된 테스트 코드는 영원히 요지보수 해야 한다.
  2. 유지보수성을 위해서 절대 내부 구현 사항은 테스트 하지 않는다(너무 내부적인 사항까지 테스트 하지 않는다).
  3. 재사용성을 높이자(테스트 유틸리티). 따라서 테스트용 함수나 클래스를 별도로 만들어서 관리하자.
  4. 배포용 코드와 철저히 분리하자.
  5. 테스트 코드를 통한 문서화를 고려하자.


Structure of Test


트리플 에이와 GWT를 기억하자.

트리플 에이는 Arrange(준비), Act(실행), Assert(검증)를 나타내고, GWT는 Given(무언가가 주어졌을 때), When(코드가 이렇게 실행이 될 때), Then(그렇다면 이렇게 예상한다)을 의미한다.
  • 예시
it('should filter out only available items', async () => { // Arrange, Given const productService = new ProductService(new StubProductClient()); // Act, When const items = await productServiece.fetchAvailableItems(); // Assert, Then expect(items.length).toBe(1); expect(items).toEqual([{ itme: '🖥', available: true }]); })

각각의 단계에서 중요한 포인트.
  • Given - 준비하는 단계에서는 준비 과정을 재사용할 수 있도록 가능하다면 따로 유틸리티 함수로 정의해서 쓰는 것이 좋다.
  • When - 의도적으로 실패하는 테스트를 먼저 만들어보고, 실패했을 때에 실패하지 않도록 하기 위해서는 어떤 코드를 수정해야 하는지 꼭 확인해 보는 것이 좋다.
  • Then - 가장 마지막에 위치시키는 것이 좋다. 또한 너무 많은 로직을 하나의 테스트에서 검사하고 있지는 않은 가 고민을 해보고 만약 그렇다면 여러개의 테스트로 분리해서 사용하는 것이 좋다.


좋은 테스트의 원칙 - FIRST

  • Fast - 테스트 코드가 빠르게 수행될 수 있도록 만들어야 함. 즉, 테스트 해야 하는 코드가 만개이던지 십만개이던지 테스트 코드를 빈번하게 원활하게 수행하기 위해서는 테스트 코드가 빠른 속도로 수행이 되어야 한다. 이를 위해서 테스트 코드에서 파일, 데이터베이스, 네트워크를 실제로 사용하는 것을 지양해야 한다(대신 mock이나 stub을 활용).
  • Isolated = 최소한의 유닛으로 검증할 수 있게끔 해야한다. 정말 작은 단위를 집중해서 독립적으로 테스트 할 수 있게끔 해야 한다. 즉, 테스트가 실패했을 때 한눈에 어디서 실패한 것인지 알아볼 수 있게끔 해야함.
  • Repeatable - 반복이 가능하도록 만들어야 함. 이는 테스트 코드를 실행할 때마다 동일한 결과를 유지해야 한다는 말이다.
  • Self-Validating - 테스트 코드 스스로가 결과를 검증할 수 있게끔 해야한다. 그리고 더 나아가서 테스트 코드에 대한 자동화를 통한 검증 프로세스(CI / CD)를 가급적 사용하는 것이 좋다.
  • Timely - 시기 적절하게 테스트 코드를 작성하고 실행해야 한다. 코드를 작성할 때, 리팩토링을 하기 전에, 또는 사용자에게 배포하기 이전에 시기 적절하게 테스트 코드를 작성해서 우리가 예상하지 못한 문제를 빠르게 잡을 수 있도록 만드는 것이 중요하다.


테스트의 범위


Right-BICEP이라고 한다.
여기서 Right는 모든 요구 사항이 정상 동작하는지 확인하는 것을 말하고,
BICEP은 다음과 같다.
  • Boundary conditions - 모든 코너 케이스에 대해 테스트, 예를 들어 잘못된 포맷의 인풋, null, 특수문자, 잘못된 이메일 형식, 작은 숫자, 큰 숫자, 중복, 순서가 맞지 않는 것들에 대한 모든 케이스에 대해서 테스트 해야 한다.
  • Inverse relationship - 역관계를 적용해서 결과값을 확인, 테스트 코드의 일관성 유지를 위함이다.
  • Cross-check - 다른 수단을 이용해서 결과값이 맞는지 확인하는 방식.
  • Error comditions - 예상한 에러에 대해서 우아하게 처리를 하고 있는지 확인하는 방식.
  • Performancs characteristics - 성능 확인은 테스트를 통해 정확한 수치로 확인하는 방식. 즉, 성능 개선의 척도와 확인도 데이터를 통해 확인해야 한다.


테스트의 조건


CORRECT 라는 원칙에 대해서 얘기해보자.

Conformance - 특정 포맷을 준수하는지 확인하는 테스트 코드가 있어야 한다.
Ordering - 순서 조건을 확인하는 테스트 코드가 있어야 한다.
Range - 예상하는 인풋이 우리가 원했던 범위를 벗어났을 경우를 대비하는 테스트 코드가 있어야 함.
Reference - 외부 의존성 유무나 특정한 조건의 유무를 테스트 하는 코드가 필요함.
Existence - 값이 존재 하지 않을 때 어떻게 동작할 것인지에 대한 테스트 코드.
Cardinality - 0-1-N 법칙에 따라 검증, 하나도 없을때, 하나만 있을때, 여러개가 있을때에 대한 테스트 코드.
Time - 상대, 절대, 동시의 일들에 대해 코드가 어떻게 반응해야 하는지에 대한 테스트 코드가 필요하다.

# TDD# test
© 2021 Createhb21.