Welcome :っ)

Devlog/CS

테스트 코드와 TDD 이해하기

lazy.won 2022. 7. 11. 20:35
728x90
반응형

 

 

 

 

 

 

 

인프런 "모든 개발자의 실무를 위한 필수 기본기 클래스" 강의를 듣고 정리한 내용 + 따로 검색하여 공부한 내용입니다. 

 

 

 

 

 

테스트 기본 이해하기

💡 테스트, 테스트 코드란 무엇인가?

  • 소프트웨어를 테스트하는 작업이다. 숨겨진 버그는 없는지, 여러 명이 동시에 이용할 때에도 잘 견디는지 등 문제를 점검하는 일이다.
    • 제품 혹은 서비스 품질을 확인하는 용도
    • SW의 버그 찾는 용도
    • 제품(함수, 특정 기능, UI, 성능, API 스펙)이 예상하는 대로 동작하는지 확인 및 검증을 하는 것이다. 
  • 보통 우리가 local 환경에서 테스트를 하는데, 백엔드는 postman을 이용하여 api 테스트를 하고, 프론트엔드는 로컬에서 브라우저에 접속하여 테스트를 하게 된다. 이 경우, 혼자서 테스트한다는 단점이 있다. 또한 사람이 하다 보니 일관성이 없고 놓치는 부분이 있기 마련이다.
  • 테스트 코드를 잘 작성해 둔다면, 버그에 견고한 코드를 작성할 수 있다. 여러 명이 있는 팀에서 SW의 버그를 줄이고 안전하게 코드를 개발하기 위한 핵심 장치라고 볼 수 있다.

 

 

테스트 종류

출처:https://betterprogramming.pub/the-test-pyramid-80d77535573

 

목표와 플랫폼, 환경에 따라 다양한 테스트가 존재한다. 위 그림처럼 테스트 피라미드라고 부른다. 

 

유닛 테스트 (Unit Test)

  • 가장 작은 단위의 테스트로,  독립적인 하나의 컴포넌트, 함수, 모듈, 클래스 등 하나의 단위를 테스트 하는 것이다.

 

통합 테스트 (Integration Test)

  • 유닛 테스트보다 더 여러 요소를 통합한 테스트
  • 의존성 있는 객체들의 정상 작동 여부까지 포함하는 테스트로, 통합했을 때 모듈들과 클래스들끼리 서로 상호작용이 잘 되는지 테스트하는 것이다.
  • 일반적으로 통합테스트는 외부 의존성을 포함하고 있는 경우가 많다. 하지만 테스트 환경은 운영 환경과 분리되어야 한다. 따라서 테스트에서 재현할 수 없는 외부 의존성 (운영 DB, 운영 API 서버 등)은 테스트 더블을 사용한다.

 

E2E 테스트 (E2E Test)

  • End to End의 약자로, 끝에서 끝, 즉 클라이언트 입장에서 테스트하는 것이다. UI 테스트, 사용자 테스트라고 하기도 한다. 
  • E2E 테스트를 하게 되면 통합 테스트나 유닛 테스트도 유기적으로 하게 된다.
  • E2E 테스트는 서버 내부 동작은 전혀 관여하지 않은 채, 철저히 엔드 유저 입장에서 서버를 이용하는 시나리오대로 테스트해보는 것이다.
  • E2E테스트 도구로 Cypress, TestCafe, Selenium Webdriver 등이 있다.
  • Docker Compose : E2E 테스트 환경 만들 때 격리된 테스트 환경을 편하게 구축해 줄 수 있는 것

 

 

비용적인 측면

Unit Test -> E2E Test로 올라갈수록 비용이 비싸진다. 테스트 코드 작성도 유닛 테스트가 쉬우며 실행, 수행, 자동화 시에도 비용이 거의 들지 않는다. E2E Test (사용자 테스트) 시에는 그 환경과 플랫폼을 제공하는 비용이 많이 든다. 

 

개발적인 효율성 측면에서도 유닛테스트가 훨씬 저렴하다. 개발 시 유닛 테스트를 작성하면 오류나 버그를 즉각적으로 캐치하여 해결 가능하지만, 모듈이나 크래스가 다 완성된 다음 서로 상호작용하거나 사용자가 사용하는 상위 레벨만을 테스트해서 문제가 발생한다면, 버그를 찾고 문제를 추적하는데 더 오랜 시간이 소요된다. 

 

 

 속도적인 측면

아무래도 단위 테스트가 가볍기 때문에 Unit Test가 빠르고 위로 갈수록 느려진다. 

 

 

 

피라미드 테스트 외에도 상황과 목적에 따라 아래와 같은 다양한 테스트가 존재한다. 
 - Contract Test
 - A/B Test
 - Stress Test

 

 

 

🙋‍♀️잠깐, 테스트 코드가 필요한 이유가 뭘까?!

  • 테스트 코드는 프로젝트 코드에 대한 가장 정확한 문서가 된다. 문서화의 효과를 얻을 수 있다. 
  • 제품/기능에 대해 자신감을 얻을 수 있다. 기능이 정상 동작하는지 확인이 가능하다. 
  • 요구사항을 만족할 확률이 높아지며 이슈에 대해 예측할 수 있다. 
  • 유지보수가 쉬워지고, 코드 품질도 향상된다. 코드간 의존성을 낮추어 독립적이고 재사용 가능한 코드를 작성할 수 있다. 
  • 리팩토링과 지속적인 개발을 위해 필수적이다. 
  • 무엇보다도 시간을 절약할 수 있다. 미리미리 버그를 찾고 개선할 수 있기 때문에 시간을 허비하지 않아도 된다. 

 

 

 

 

 

의존성을 대체하는 테스트 더블

💡 테스트 더블이란?

외부 의존성을 끊어내어 테스트할 수 있게 하는 것이다. 의존성 객체들을 대체함으로써 테스트를 좀 더 원활하게 진행하기 위한 객체라고 보면 된다.

 

참고(https://martinfowler.com/bliki/TestDouble.html)

 

 

테스트 더블의 종류

  • dummy
    • 실제 내부 동작은 구현하지 않은 채, 객체의 인터페이스만 구현한 테스트 더블 객체
    • 간단하게 테스트할 때 사용
  • stub
    • dummy 테스트 더블 객체에서 테스트에 필요한 최소한의 구현만 해둔 테스트 더블 객체
    • 테스트에서 호출될 요청에 대해 미리 준비해둔 결과만을 반환함
  • spy
    • stub에서 테스트에 필요한 정보를 기록해두는 테스트 더블 객체
    • stub의 역할을 포함
    • 실제로 내부가 잘 동작했는지 등을 별도 인스턴스 변수로 기록해둠
  • fake
    • 동작의 구현은 갖추고 있지만, 테스트에서만 사용할 수 있는 테스트 더블 객체
    • 대체할 객체가 복잡한 내부 로직이나 외부 의존성이 있을 때 사용
  • mock
    • mocking 한다 = 외부 의존성을 끊어준다.
    • 테스트에 필요한 인터페이스와 반환 값을 제공해주는 객체
    • 해당 메서드가 제대로 호출되었는지를 확인하는 행위 검증의 기능을 가짐
    • 다른 테스트 더블과 다르게 보통은 객체를 직접 정의하지 않고, 보통 Mock 객체로 반환 값을 미리 지정해둔다.
    • 대부분의 테스트 프레임워크는 Mocking을 정밀하게 할 수 있도록 지원해준다.

 

 

 

 

 

TDD 기본 개념

💡 TDD란 무엇일까? 

TDD(Test-Driven Development)는 테스트가 개발을 이끌어가는 방법론이다. 즉, 테스트가 개발보다 선행하게 되는 것이다. 
개발(코드 작성) 전에 테스트코드를 먼저 작성하면서 개발해나가는 방식이다. 
 

 

 

TDD 과정

  1. 요구사항을 테스트코드로 먼저 작성하기
  2. 테스트 대상 구현하기
  3. 테스트 대상 SRP 원칙을 지키도록 리팩토링하기
  4. 위 TDD 개발 과정을 레드-그린-리팩토링 이라고 한다.
    1. 실패 → 성공 → 리팩토링의 순환을 가지는 “레드-그린-리팩토링“ 순서로 개발하는 것이다.

 

 

 

  1. 일단 먼저 실패하는 테스트 코드를 작성한다. 아직 구현체가 작성되지 않았으므로 테스트는 실패한다. 
  2. 테스트가 통과될 정도의 간단한 구현 코드를 작성한다. 구현이 완료되어 테스트는 성공한다. 
  3. 기존 코드를 필요에 따라 리팩토링 한다. 

이 과정을 무한 반복하면서 개발한다. 

 

 

 

 

TDD 장단점

장점

  • TDD를 하면 꼼꼼한 테스트를 통해 코드 품질과 테스트 코드의 문서화 품질이 올라간다.
  • 기대하는 것을 테스트 코드로 미리 명확하게 정의할 수 있다. 그래서 사용하기 좋은 코드를 작성할 수 있게 된다.
  • 테스트를 훨씬 꼼꼼하게 작성하게 된다.
  • 테스트코드를 먼저 작성하기 때문에 요구사항 분석 및 철저한 이해를 하게 된다. 이후에 어떤 식으로 코드를 짤 것인지 설계를 할 수 있다. 그래서 코드 개발하기 앞서 모든 요구사항(목표)에 대해 점검할 수 있으며, 구현할 때 사용자 입장에서 코드를 작성할 수 있다. 
  • 테스트 코드가 깔끔한 코드 사용 문서가 된다.
    • TDD에서 테스트 코드는 테스트할 대상의 구현을 모른 채 작성되기 때문에, 철저히 사용자 중심적으로 작성된다. 따라서 테스트 코드는 코드를 사용하기 위해 필요한 최소한의 내용만 담게 된다.

단점

  •  테스트가 가능하도록 코드를 설계하는 것은 어렵다.
    • 추상화, 의존성 주입 등을 잘 활용해야 테스트 가능하도록 코드 설계가 가능하다.
  • 익숙하지 않은 채 TDD를 진행하면 개발 프로세스가 느려질 수 있다.

 

 

 

🙋‍♀️잠깐, TDD는 꼭 해야 할까?!

  • TDD를 하는 경우는 아래와 같다.
    • 요구사항이 명확한 경우
    • 비즈니스 로직인 경우
    • 협업 시 명세서(문서) 역할을 하기 위해 
    • 설계에 대한 고민이 필요한 경우
  • 대부분의 사람들이 UI 컴포넌트를 작성할 때는 TDD를 하진 않는다. 
  • TDD를 할 때도 있고, 하지 않을 때도 있지만, 명백한 사실은 사용자에게 배포하는 코드라면 해당 기능에 대한 테스트 코드는 반드시 작성해야 한다. 코드 리뷰를 요청하기 전 main repository에 코드를 머지하기 전에, 코드와 테스트 코드를 포함해서 머지해야 하며, 좋은 문서화를 위해서라도 테스트 코드는 꼭 작성하는 것이 좋다. 

 

 

 

 

 

 

참고

https://ui.toast.com/fe-guide/ko_TEST

 

테스트

자바스크립트는 최근 몇 년간 비약적인 발전을 통해 사용 범위를 넓혀오고 있으며, 프론트엔드 환경에서 요구하는 애플리케이션의 수준도 나날이 복잡해지고 있다. 이와 더불어 자바스크립트

ui.toast.com

https://tech.kakao.com/2021/11/08/test-code/

 

테스트 코드 한 줄을 작성하기까지의 고난

- 이 글에서 설명한 내용은  if(kakao)2021 에서 보실 수 있습니다. 안녕하세요. 창작자앱개발파트의 Ronda입니다. 창작자 앱 개발파트에서 브런치와 티스토리 안드로이드 앱을 개발하고 있습니다.

tech.kakao.com

 

320x100
반응형

'Devlog > CS' 카테고리의 다른 글

객체 지향 프로그래밍이란?  (0) 2022.08.07
객체지향 5대 원칙 - SOLID 원칙  (0) 2022.08.06
쿠키와 세션, 인증 이해하기  (0) 2022.06.24
OSI 7계층과 TCP/IP 4계층 모델  (0) 2022.06.22
프로그램 운영 기본 지식  (0) 2022.06.21