Spring_테스트

황호준·2023년 9월 4일

CS

목록 보기
29/29

DDD (Domain-Driven Design)

  • 도메인 주도 개발/ 도메인 패턴을 중심에 놓고 설계하는 방식
    사용 목적
    • 도메인 모델의 적용 범위를 구현까지 확장하여 도메인 지식을 구현 코드에 반영한다.
    • 공통의 언어를 사용하여 도메인과 구현을 충분히 만족하는 모델을 만든다
    • 실제 코드로 구현 가능한 현실성 있는 도메인 모델 분석과 그것을 추상화하는 설계이다.

TDD(Tset Driven Development)

  • 테스트 주도 개발/ 기존 개발 프로세스와는 다르게 테스트 케이스를 작성한 후 실제 코드를 개발하여 리펙토링하는 절차 (개발 속도가 느려지는 단점이 있음)

TDD의 사용목적

  1. 불확실성이 높을 때 "피드백"과 "협력"이 중요하기 때문에 피드백과 협력이 자주 이루어 진다면 더 좋은 결과가 나올 수 있다.
  2. 만약 특정 부분에서 코딩을 여러번 해봤고 결과에 대한 숙지가 완벽하다면 TDD를 하지 않아도 된다.
  3. TDD를 했을 때 얻는 것이 적다면 TDD를 하지 않아도 된다.

하지만
• 익숙하지 않은 프로그램 주제
( 나에 대한 불확실성이 높은경우 )
• 고객의 요구조건이 바뀔 수 있는 프로젝트
( 외부적인 불확실성이 높은경우 )
• 개발하는 중에 코드를 많이 바꿔야한다고 생각하는 경우
( 전체적인 불확실성이 높은경우 )
• 개발 이후 이 코드를 누가 유지보수할지 모르는 경우

Junit

• 자바 프로그래밍 언어용 유닛 테스트 프레임워크
• 테스트 결과는 Test클래스로 개발자에게 테스트 방법 및 클래스의 History를 공유 가능
• 단정(assert) 메서드로 테스트 케이스의 수행 결과를 판별
• 어노테이션으로 간결하게 지원(JUnit4부터)

Jnunit5

  • JUnit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

Junit4 vs Junit5

  1. 어노테이션의 차이
  2. Reflection에 의존하지 않아도 됨
    • Junit4에서는 plugin과 ide의 통합 지원이 없었기 때문에 reflection에 의존해야만 했다.
    • Junit5 부터는 JUnit Platform이라는 테스트코드 통합 지원 플랫폼이 제공되어 테스트 코드 실행이 해당 플랫폼 위에서 수행된다.
  3. 다양한 기능의 추가
    • Junit4에서 있었던 기능들이 신규로 추가/개선되어 제공되고 있다. Junit5 도입시 보다 더 다양한 기능으로 테스트 코드를 작성할 수 있다.
  4. private 메소드 테스트 허용
    • junit4에서는 모든 test method는 public 접근 제한자를 선언해야만 이용이 가능했다.
    • Junit5에서는 Reflection을 통해 자동으로 테스트 클래스를 검색하여 테스트 수행이 가능해졌다.

단위 통합 인수 테스트

단위테스트

  • 테스트 가능한 가장 작은 단위로 나누어 예상대로 실행이 되는지 확인하는 테스트
    • 일반적으로 메소드,또는 클래스 단위로 진행
    • 더 작은 단위로 나눌수록 복잡성이 낮아지고 테스트하기 수월하다.
    • 최대한 간단하고 디버깅하기 쉽게 작성

통합테스트

  • 단위테스트보다 좀 더 큰 동작을 확인하기 위해 여러 모듈을 조합하여 이들이 서로 원하는대로 협력하는지 확인하는 테스트
    • 주로 자신이 짠 코드 이외에 다른 코드(라이브러리 등)를 포함하여 테스트 진행
    • 단위 테스트보다 많은 코드를 실행하기에 디버깅이 쉽지 않다
    • 단위테스트에서는 발견하지 못했던 에러를 발견할 수 있다.

인수테스트

  • 유저 시나리오에 맞춰 수행하는 테스트
    • 비즈니스적인 모임에 의해 시나리오가 결정
    • 개발자는 이에 의거해 시나리오에 맞게 테스트 작성
    • 누가,어떻게,무엇을 할 것인지에 중점을 맞추어 진행
    • API를 확인하는 테스트이기도 하다.

테스트 더블

  • 모의 객체를 생성해서 테스트 진행

    • 테스트 대상 코드 격리
    • 테스트 속도 개선
    • 예측 불가능한 실행 요소 제거
    • 특수한 상황 시뮬레이션
  • 대표적으로 Stub, Mock 외에 Dummy, Spy, Fake 등이 있지만 각각의 기술들이 명확하게 역할을 나누어 가지는 것이 아니기 때문에 대표적으로 Stub과 Mock으로 구분

Stub vs Mock

Stub(상태 검증)

  • 메서드가 수행될 때 연관되어있는 협력 객체의 '상태'를 검증함으로써 제대로 기능이 동작하고 있는지를 검증
    • 더미 객체를 생성하고 실제로 동작하는것처럼 보이게 만든 가짜 객체
    • 호출된 요청에 대한 응답값을 미리 만들어놓고 전달
    • 객체의 최소한의 기능만을 임의로 구현

Mock(행위 검증)

  • 테스트하고자 하는 메소드가 참조하고 있는 협력 객체의 메소드를 제대로 콜 하는지에 대한 '행위'를 검증)
    • 특정 동작을 수행하는지에 대한 검증
    • 행위검증을 추구한다는 점에서 다른 테스트 더블과 구분

SpringBoot 계층별 테스트 방법

Domain

  • JUnit, AssertJ 등 테스트 편의 도구를 이용해서 테스트한다.

Repository

  • 인메모리 DB를 사용하고, JPA 관련 설정만 불러오는 @DataJpaTest를 이용해서 Repository의 동작(저장 및 조회)에 대해 테스트한다.
  • 저장을 위한 JPA 연관 관계가 적절히 구성되었는지, Repository 메소드가 제대로 구현되었는지 확인하는 것을 목적으로 한다.
  • JPA 관련 어노테이션 없이 코드를 작성해서 저장에 실패하는 테스트 코드를 먼저 작성하고, JPA 규칙에 맞는 어노테이션을 추가해서 테스트 코드를 통과시킨다.
  • 기본적으로 인메모리 DB를 사용하나 테스트에 사용할 DB를 지정할 수 있다.

Service

  • 트랜잭션을 관리하는 것이 주요 책임(CRUD에 대한 책임은 Repository에 역임)
  • Repository의 동작은 Repository Test에서 확인했으므로 Repository의 메소드가 제대로 호출되는지만 확인하면 되므로 실제 Repository가 아닌 Mock Repository를 사용한다.
  • Mockito를 사용하므로 실제 저장/조회가 발생하지 않는다.
  • 생성, 삭제, 조회 시에는 생성/삭제/조회를 호출하는 메서드 호출 여부를 verify 하고, 수정 시에는 명시적으로 save()나 saveAndFlush()가 호출되지 않을 수도 있으므로 verify 로는 테스트가 불가능하므로 Mock 에 사용되는 엔티티나 DTO의 상태 변경을 assert 한다.

Controller

  • 넓게 보면 사용자가 보낸 요청을 서비스에 전달하기까지 모든 과정을 포괄한다고 볼 수 있지만, 필터, 인터셉터, 요청 라우팅, 보안(인증, 인가), 데이터 validation, 데이터 바인딩 등은 스프링 프레임워크에서 담당해주므로 컨트롤러가 실제로 담당하는 부분은 이를 모두 통과한 후의 요청 데이터를 서비스에 전달해주고, 서비스가 반환하는 결과를 클라이언트에게 반환하는 부분
  • 컨트롤러의 로직이 많지 않은 경우 서비스를 Mock 해서 컨트롤러 레이어만을 단위 테스트하는 것은 효용이 크지 않을 수 있으므로, 컨트롤러 테스트는 보통 Mock 대신 실제 서비스 및 도메인 계층을 대상으로 통합 테스트로 작성하는 편이 낫다.

테스트 커버리지(JACOCO)

테스트 커버리지

  • 소프트웨어의 테스트가 얼마나 효과적으로 소스 코드를 실행하고, 얼마나 많은 코드를 검사하는지를 나타냄 높은 테스트 커버리지는 코드의 신뢰성과 품질을 높이는 데 도움이 될 수 있음

JACOCO

  • java Code Coverage를 측정하는 라이브러리

Code Coverage

  • 소프트웨어의 테스트코드가 얼마나 많은 코드를 충족시키고 있는지에 대한 지표중 하나, 즉 실행시 테스트가 코드의 얼마나 많은 부분을 실행했는지에 대한 수치

JACOCO를 사용함으로써 소스 코드를 컴파일하고 실행하는 동안 커버리지 정보를 수집 후 보고서 형태로 커버리지 정보 제공하여 개발자가 코드의 테스트 커버리지를 분석하고 개선 할 수 있도록 도와줌

profile
기록 블로그

0개의 댓글