본문 바로가기
회고이야기/세미나

[세미나] 무엇을 테스트할 것인가? 어떻게 테스트할 것인가?

by 사랑꾼이야 2022. 9. 3.
반응형

해당 내용은 아래 유튜브 영상을 토대로 필요한 내용 위주로 정리하였습니다.

테스트로부터 얻을 수 있는 것

  • 안정감과 자신감
  • 안정감과 자신감을 얻을 대상은?
    • 현재와 미래의 나
    • 현재와 미래의 동료
  • 좋은 프로젝트란?
    • 나를 포함해서 많은 사람들에게 안정감과 자신감을 줄 수 있는 것

무엇을 테스트할 것인가?

  • 구현 테스트
  • 테스트 가능한 것과 불가능한 것 구분

구현 테스트

  • private 이면 어떻게 테스트 해야 하지?
    • reflection 을 활용하면 테스트는 가능하지만 그렇게까지 해야 할까?
    • 공개된 메소드의 여러 테스트 케이스를 더 추가하면 private 메소드까지 커버가 될 수 있습니다.
  • 우리가 코딩을 한 것이 테스트 케이스가 되는 것이 아니라 설계한 것이 테스트 케이스가 되어야 합니다.

구현이 아닌 설계를 테스트

테스트 불가능한 것

  • 제어할 수 없는 영역
    • Random, Shuffle, LocalDate.now()
    • 외부 세계
    • HTTP
    • 외부 저장소
    • 외부 세계에서는 다양한 환경이 생길 수 있습니다.
    • 외부 세계의 서버에서는 조건의 값이 변경되었거나, 배포가 되지 않아서 서버가 내려갔거나, 서버가 다운되었거나..
  • 제어할 수 없는 영역은 멱등한 결과를 보정할 수 없습니다.

항상 성공할 수 있는 것, 항상 동일한 결과가 나올 수 있는 것을 테스트

어떻게 테스트할 것인가?

테스트 가능한 것, 불가능한 것

  • 테스트할 수 없는 메소드가 테스트할 수 있는 메소드까지 다 오염시킨다.
  • 테스트할 수 없는 메소드를 Boundary Layer 까지 수평하게 끌어올려서 테스트를 하게 되면 테스트할 수 없는 영역을 최소화하고 테스트할 수 있는 영역을 많이 확보할 수 있습니다.
    • Boundary Layer 는 한 모듈로서의 의미를 지니는 가장 바깥 쪽

테스트 불가능한 영역을 Boundary Layer 로 올려서 테스트가 가능하도록 변경

Java와 Spring Framework

  • Spring Framwork Bean으로 만들어야합니다?
    • Spring Context 안에서 single object 보장을 해야되기 때문입니다.
  • Test 는 Boot! 로
    • Spring을 사용한다고 Spring Context를 사용해야 할까요?
    • Spring Context 가 필요할까요?
    • 기존 테스트에서는 Spring Context가 없이도 테스트가 가능하였습니다.
  • Spring Context 는 느립니다.
    • 이런 결과는 빠른 피드백을 받을 수 없게 됩니다.

의존성

  • Spring Framework 에서 이 필드의 의미는?
  @Autowired   private MemberService memberService
  • 필수 의존성
    • 자바에서 이 필드의 의미는?
  private MemberService memberService
  • Nullable
    • Spring Context 의 오용은 언어의 본질을 망각하게 할 수 있다.
  • Java 개발자인지, Spring Framework 개발자인지

Context, Framework 종속적이지 않은 테스트를 우선

Test Double

  • 무엇을 Test Double 로 처리해야 할지 정해야 합니다.
    • Test Double 을 사용하는 것은 테스트가 구현을 알아야 한다는 것입니다.
    • Test Double 의 남용은 구현 테스트로 유도할 수도 있습니다.
    • 정말 테스트할 수 없을 때 Test Double 사용합니다.
    • 편리하지만 사용을 의식하여 최소화합니다.
    • 순수 자바 애플리케이션으로는 테스트할 수 없는 것이 대상이 될 수 있습니다.
  • 저장소 입출력 검증
  • SPEC 검증
    • 내부 Controller
    • 외부 API

Embedded

  • 종류
    • RDB -> h2database/h2
    • Redis -> kstyrc/embedded-redis
    • Mongo -> flapdoodle-oss/de.flapdoodle.embed.mongo
    • Dynamo -> amazonaws/DynamoDBLocal
    • MQ -> softwaremill/elasticmq
    • SQS -> jojoldu/spring-boot-aws-mock
  • 제어할 수 없는 영역을 제어 가능하도록 만들 수 있습니다.
  • 테스트와 Embedded 시스템은 동일한 라이프 사이클을 갖도록 구성해야 합니다.
    • 테스트가 시작되면 Embedded도 시작해야 하며, 테스트가 종료되면 Embedded도 종료되어야 합니다.
  • 특징
    • 테스트 정확도 Local > Embedded
    • 테스트 피드백 속도 Local < Embedded
    • 테스트 안정성 < Embedded

EndPoint Test

  • Spring Framework Support
    • MockMvc
    • REST Assured
    • WebTestClient

테스트의 목적은 요청과 응답 스펙 검증만으로 제한하는게 정신 건강에 좋을 것이라고 생각

  • 테스트와 문서를 현행화
    • Spring REST Docs

TIP & RULE

1.테스트는 상호독립적으로 작성

  • 모든 테스트의 순서와 관계를 생각하며 테스트를 작성하기 어렵습니다.
  • 공유되는 자원을 초기화하여 다른 테스트에 영향을 받지 않도록 해야합니다.
  • 테스트간 서로 영향을 미치지 않도록 테스트는 상호 독립적으로 작성해야 합니다.
  • 테스트의 순서가 필요할때 JUnit 5의 DynamicTest 추천

2. 테스트 안에 의도와 목적이 드러나도록 작성

  • 작성하려고 하는 테스트 메소드 안에 모든 의도와 목적이 들어나도록 작성
@Test
{
    어떠한 조선에서
    무엇을 수행했을 때
    어떤 결과가
}
  • 테스트 메소드만 보고 무엇을 테스트하는지 파악할 수 없으며 관련 정보를 찾아봐야 합니다.
Import.sql
@Before
TestConfiguration
@Test
어떠한 조건에서 무엇을 수행했을 때

@Test
{
    어떤 결과가
}

3. 테스트 코드도 리팩토링 대상

  • 시간의 흐름에 따라 코드는 늘어갈 것이며
  • 시간이 흐름에 따라 코드와 테스트는 늘어갈 것입니다.
  • 코드양에 대한 이야기가 아닌 가독, 안정성, 요규사랑 정리 등 비지니스 코드와 동일한 수준의 리팩토링이 함께 이루어져야 합니다.

정리

  • 무엇을 테스트할 것인가?
    • 설계를 테스트
    • 테스트 가능한 것을 테스트
  • 어떻게 테스트할 것인가?
    • 테스트 불가능한 영역을 Boundary Layer 까지 올려서 테스트 가능하도록 변경
    • Context, Framework 종속적이지 않도록 테스트
    • Test Double 사용
    • Embedded System 사용
    • EndPoint Test 도구 사용하여 내부 API Spec 테스트
  • TIP & RULE
    • 테스트는 상호 독립적으로 작성
    • 테스트 안에서 의도와 목적이 모두 드러나도록 작성
    • 테스트 코드 리팩토링

내용 정리

테스트는 코딩의 대한 테스트가 아니라 설계의 대한 테스트를 진행해야 합니다. 테스트가 가능한 것을 테스트 진행하되, private 메소드를 테스트하기보다는 테스트 케이스를 늘려서 테스트 범위를 넓히는 것이 중요합니다.
테스트를 진행시 테스트가 불가능한 영역(날짜, 랜덤, 외부 세계 의존 등)들이 존재하는데, Boundary Layer 까지 올려서 테스트 범위 영역을 올려서 테스트를 작성합니다. 또한 Spring Framework를 통해 생성된 Bean들은 테스트의 많은 시간을 사용하게 됩니다. Spring Framework의 의존적이지 않는 테스트를 작성하고 시간을 단축하여서 테스트의 결과를 빠르게 피드백 받을 수 있도록 헤야합니다. 외부 세계의 경우 필요하면 Test Double을 사용하고 Embedded System을 사용할 수 있습니다.

반응형

댓글