테스트의 필요성과 3분류

Gyeongjae Ham·2023년 6월 18일
0

TEST

목록 보기
1/7
post-thumbnail

이 시리즈는 TDD를 숙달하기 전에 TEST 자체에 대한 이해를 높이기 위한 학습 시리즈입니다

테스트의 필요성

레거시 코드란?

마이클 C.페더스
"내게 레거시 코드란, 단순히 테스트 루틴이 없는 코드다. 다만 이 정의는 다소 불완전하다"

Regression

  • 잘 돌아가던 코드가 최근 배포로 인해서 동작하지 않는 상황을 Regression이라 합니다
  • 이런 경험이 한 두번 쌓이게 되면, 전체적으로 수정과 배포 자체의 두려움이 커지게 됩니다
    1. 2005년 구글 웹서버의 생산성이 급격히 떨어지는 문제가 발생했습니다
    2. 설상가상 이 시기에는 릴리즈 주기도 길었고, 버그도 많아졌습니다
    3. 아무리 똑똑한 엔지니어를 투입해도 문제는 해결되지 않았고, 항상 불안에 떨며 배포를 했습니다
    4. 테크 리더는 자동 테스트를 도입하기로 결정합니다
    5. 팀원들은 자신있게 배포를 할 수 있게 되었고, 그 결과 생산성이 올라가게 됩니다

좋은 아키텍처란?

  • 기본적으로 SOLID 원칙을 준수하기 위해 노력한 아키텍처는 좋은 아키텍처에 가깝습니다
  • 또한 TESTSOLID 원칙은 생각보다 긴밀한 관계를 맺고 있습니다
  • TESTRegression을 방지하기 위한 거라면, SOLID 원칙은 TEST하기 쉬운 구조를 가지게 하는 상호보완적인 관계를 가지고 있습니다

SOLID

SRP(단일책임의 원칙: Single Responsibility Principle)

  • 클래스는 단 한개의 책임을 가져야합니다
  • 클래스를 변경하는 이유는 단 하나여야만 합니다
  • 이를 지키지 않으면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향을 미칠 수 있게 됩니다
    → 이렇게 되면 유지보수가 매우 비효율적
  • 테스트는 명료하고 간단하게 작성해야 하기 때문에, 단일 책임 원칙을 지키게 됩니다
  • 테스트가 너무 많아져서 이게 무슨 목적의 클래스인지 눈에 안들어오는 지점이 생기게 됩니다
    • 이 때가 클래스를 분할해야 하는 시점, 그러면서 책임이 자연스럽게 분배됩니다

OCP (Open-Closed) 개방-폐쇄 원칙

  • 확장에는 열려있어야 하고, 변경에는 닫혀 있어야 합니다
  • 즉, 기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계해야 합니다
  • 이를 지키지 않으면 instanceof 와 같은 연산자를 사용하거나, 다운 캐스팅 발생합니다
  • 테스트 컴포넌트와 프로덕션 컴포넌트를 나눠 작업하게 되고 필요에 따라 이 컴포넌트를 자유자재로 탈부착이 가능하게 개발할 수 있게 됩니다

LSP (Liskov Substitution) 리스코프 치환 원칙

  • 하위 타입 객체는 상위 타입 객체에서 가능한 행위를 수행할 수 있어야 합니다
    • 즉, 상위 타입 객체를 하위 타입 객체로 치환해도 정상적으로 동작해야 함
  • 이상적으로 테스트는 모든 케이스에 대해 커버하고 있으므로, 서브 클래스에 대한 치환 여부를 테스트가 알아서 판단해 줍니다

ISP (Interface Segregation) 인터페이스 분리 원칙

  • 클라이언트는 자신이 사용하는 메소드에만 의존해야 한다는 원칙입니다
  • 인터페이스는 해당 인터페이스를 사용하는 클라이언트를 기준으로 잘게 분리되어야 합니다
  • 테스트는 그 자체로 인터페이스를 직접 사용해볼 수 있는 환경입니다. 따라서 불필요한 의존성을 실제로 확인할 수 있는 샌드박스입니다

DIP (Dependency Inversion) 의존 역전 원칙

  • 의존 관계를 맺을 때, 변하기 쉬운 것(구체적인 것)보다는 변하기 어려운 것(추상적인 것)에 의존해야합니다
  • 가짜 객체를 이용하여 테스트를 작성하려면, 의존성이 역전되어 있어야하는 경우가 생깁니다

테스트의 3분류

  • 전통적으로 나누는 테스트 3분류는 API 테스트 부분을 제외하면 그 각층의 의미가 어느 선까지인지 정의가 사람마다 다를 수 있습니다
  • 따라서 여기에선 규모로 구분지어둔 구글의 테스트 3분류를 보고 각 의미를 살펴보겠습니다

small(소형) 테스트

  • 단일 서버
  • 단일 프로세스
  • 단일 스레드
  • 디스크 I/O 사용해선 안됨
  • Blocking call 허용 안됨

  • 소형 테스트를 단위 테스트라고 칭합니다
  • 테스트에서 소형 테스트는 매우 중요합니다
    • 소형 테스트에서 결과는 매우 확정된 결과로 나오고 이는 테스트 속도의 증가로 이어집니다

medium(중형) 테스트

  • 단일 서버
  • 멀티 프로세스
  • 멀티 스레드
    -> h2 같은 테스트 DB를 사용할 수 있습니다

  • 소형 테스트보다 느립니다
  • 멀티 스레드 환경에서 항상 동일한 동작을 보장하지 못할 수 있습니다
    • h2 같은 외부 모듈의 동작에 따라서 달라지기 때문입니다
  • 스프링 개발자들이 너무 많이 만드는 테스트이기도 합니다
  • 하지만 피라미드 구조를 보면 알 수 있듯이 소형 테스트가 전체 테스트의 80%를 차지해야 합니다

large(대형) 테스트

  • 멀티 서버
  • End to end 테스트
profile
Always be happy 😀

0개의 댓글