테스트에 대한 개요와 개발자가 해야할 고민

존스노우·2023년 11월 1일
0

테스트

  • 어떤 시스템이 제대로 동작하는지 검증하는 과정
  • 인수테스트(체크리스트를 받아서 테스트) / 자동테스트(내가하는것)

  • 개발자가 저지르는 대표적인 실수
  • 인터페이스를 생각하지않고 구현체를 먼저만든다
  • red단계에서 컴파일 코드만들고 테스트 실패확인 -> 그래서 개발자는 구현체 보다 인터페이스 작성하는걸 집중 한다.
  • 어떤 책임을지고 어디까지 해결해야하는지

  • 인터페이스에 집중한다? 객체지향의 핵심원리중 하나인 행동에 집중하는 말과 같다.
  • 다시 말하면 TDD가 책임 주도 설계 핵심 과정인

  • What/who 사이클을 고민하게 도와준다.
  • 어떤 행위를 누가 수행할지 결정하는 과정

  • 이 차트는 좋은 설계 나쁜 설계 에도 적용되
  • 테스트와 아키텍처는 비례함

테스트 고민

무의미한 테스트

  • 이리 명확한 코드에 테스트 코드가 의미가 있을까?
  • Jpa구현체가 알아서 잘했을 텐데.
  • 분명히 의미는 있지만 커버리지가 목적인 테스트가 된다.

  • 행동에 집중한다는 의미에서 행동이 메서드나 함수를 의미하는게아님
  • 모든 메서드 테스트 보다 중요한 로직 구분해서 테스트를 해야함.

느리고 쉽게 깨지는 테스트

  • 방금 위테스트가 200개가되면? 1분이 걸림 적지않는 부담 시간
  • 현업은 200개 테스트 쉽게 넘어감

테스트가 불가한 코드

  • 이건 어떻게 테스트를..

  • 이걸 어떻게함
  • mock을 사용하면 설계를 발전시킬수 없다.

-> 이런 고민을 하는테스트가 개선해야하는 신호다 ! 강제로 테스트하지말고

테스트 필요성 및 3 분류

  • 정확한 기준?
  • 오래된거?
  • 테스트 루틴이 없는 코드

좋은 아키텍쳐 좋은 설계

  • 솔리드한 코드가 좋은 설계이다.

  • 둘은 긴밀한 상호보완적 관계
  • 솔리드 원칙이 지켜지면 경계가 만들어지고 회귀버그 방지
  • 서로에게 영향을 줌

  • 가운데를 추구해야된다
  • 좋은 설계를 놓쳐서 안되고 회귀버그도 놓쳐선 안된다

  • 클래스하나에 테스트 클래스 하나가 만들어짐.
  • 만약 너무 많아지면? 클래스를 분할해야될 때
  • 자연스럽게 분배된다

  • 테스트 작성하다보면 이 원칙을 지킬수 밖에 없다
  • 테스트용 컴포넌트와 프로덕션 컴포넌트를 나눠서 작업해야함

  • 슈퍼클래스 계약을 서브클래스가 제대로 치환하는지 확인하라!
  • 이상적으로 테스트는 모든 케이스에 대해 커버하고 있어야 되니
  • 치환 여부도 테스트가 알아서 판단하겠지 맞네

  • 인터페이스가 너무 많아서 뭘 호출해야 되는거야
  • 단일책임 원칙 위배 인터페이스를 분리해줘야 된다.

  • 목을 남용하게 되면 설계를 고민한다

정리

  • 테스트를 작성한다고 솔리드가 되는게아니라
  • 테스트를 하면서 이런것을 챙겨줘야 한다.
  • 어떻게 테스트할까 고민하면 솔리드가 자연스럽게 따라옴

테스트 3분류


  • 디비를 사용할 수 있는 중형 테스트
  • 디비를 사용한다? 소형 테스트가 아니다
  • 멀티스레드 환경에서 어떻게 동작할지 몰라 결과가 항상 같은지 보장 못함
  • 중형 테스트가 많다? 가장 많이 저지르는 실수

테스트에 필요한 개념

sut?

  • 테스트 하려는 대상 System under test

BDD

  • 어떤 사항이 주어졌을때 이렇게하면 결과가 이렇게 해줌

  • 테스트를 작성하다보면 어디에 어떻게 테스트를 넣어야되지?

  • 행동에 집중해야되는걸 알려준다

  • user story 시나리오 강조

  • 상태기반 검증 내가 주로 하고 있는 방식

테스트 픽스처

  • 테스트를 하기위해 필요한 자원을 미리 생성해둠
  • sut가 테스트픽스처가 됨
  • 테스트가 한눈에 잘안들어와 선호하지않는 부분도있음 개인차이

비욘세 규칙

  • 유지하고 싶은 상태나 정책이 있다면 알아서 테스트를 만들어야 함
  • 유지하고싶은 상태가 있으면 전부 테스트해라

Testabilt

  • 테스트 가능성 지표 뒤에서 설명

Test double

  • double -> 스턴트맨 대역
  • 이런식으로 가짜객체 넣어주기

Dummy

  • 아무런 구현이없어 테스트 돌아가게하고
  • 결과 부분에서 사용자가 메일 대기인지 검증만

Fake

  • 자체로직을 들고 있음
  • 발송한 메세지를 기록하는 로직

stub

  • 주로 외부연동하는 컴포넌트들에 사용 많이함
  • 미리 준비된 값을 준비시켜줌
  • 보통 mokito이용해서 구현 됨

Mock

  • testDouble과 동일한 개념
  • 메서드 호출을 확인하기 위한 객체

spy

  • 모든 메서드 호출을 낱낱이 기록하는 객체

의존성과 TestBility

  • A 가 B를 사용한다.
  • 결합이랑 같은의미 다른객체나 함수를 사용한다는 의미
  • 의존성 주입이 의존성을 완전히 없에는게 아님

  • 의존성을 약화시킨거지 없앤 건 아님
  • 의존성을 제거? 객체간의 협력 시스템간의 협력을 부정하는건
  • 대부분의 디자인패턴이나 설계는 의존성을 약하게 하는게 목표
  • 근대 New는 사실상 하드 코드라 new를 없애는게 더 의존성을 약화시킨다고 한다.
  • 오른쪽코드는 고기를 종류별로 ! 여러가지로 넣어줄수 있음

의존성 역전

  • 주입과 역전 끝에가 다르다



  • 상위 하위 모듈은 모두 추상화에 의존해야 한다.
  • 세부사항이 추상화에 의존해야 된다.
  • 화살표가 들어오는 방향에서 나가는 방향!
  • 화살표의 방향을 바꾸는 테크닉
  • import에 사용되는 경로에는 인터페이스나 추상 클래스만 사용해야한다.
  • 이건좀 과한대..
  • 인터페이스나 추상클래스같은 추상적인 선언을 정책이라보고
  • 변동성이 큰 구체적인 요소가 세부사항으로 봐야된다.
profile
어제의 나보다 한걸음 더

0개의 댓글