Unit / Integration / Funtional Test

Happhee·2022년 5월 13일
1

💙  React 💙

목록 보기
16/18
post-thumbnail

들어가기

너무 더워,,,,☀️ 살랴주세여,,,💦

  • 베라로 달려가는 🏃‍♀️Move 함수
  • 베라 직원에게 💁‍♀️주문을 요청하는 Order 함수
  • 주문 요청 후 🍦 아수크림 🍦을 통에 담는 Gather 함수

유닛 테스트
Move, Order, Gather 함수 각각에 대해 여러 개의 입력 값을 넣어주고 제대로 된 출력 값이 나오는지 테스트하는 것이다.

통합 테스트
베라 직원에게 💁‍♀️ 주문을 요청하고, 🍦 아수크림 🍦 을 통에 담을 텐데, 실제로 DB에 🍦 아수크림 🍦이 잘 담겼는지 테스트하는 것이다.

기능 테스트
베라로 달려가 🏃‍♀️ 직원에게 💁‍♀️ 주문을 요청하고 🍦 아수크림 🍦을 통에 담는 하나의 과정이 제대로 수행되었는지 테스트하는 것이다.


✨ Unit Test

코드가 제대로 작동하는지 확인하기 위해 함수 하나하나와 같이 코드의 작은 부분인 애플리케이션의 개별 모듈을 독립적으로 테스트(종속성과의 상호 작용없이)하는 것이다.

❌ 만약 테스트에 네트워크나 데이터베이스 같은 외부 리소스가 포함된다면 그것은 유닛 테스트가 아니다 ❌

특징

  • 전체 코드 중 가장 작은 단위의 테스트이며, 보통 메서드 레벨이다.
  • A라는 함수가 실행되면 B라는 결과가 나온다 정도로 테스트한다.
  • 즉각적인 피드백이 나온다는 것이 훌륭한 장점이다.
  • 꼭 메모리 내에서만 실행되는 테스트여야 한다는 법칙은 없다.
    • DB, Network Access, File System 등을 사용하여도 단위테스트의 레벨일 수 있다.
  • 하나의 메서드들이 잘 동작한다는 것은 보장할 수 있지만, 그들이 결합되었을 때도 잘 작동한다는 것은 보장할 수 없다.
  • 테스트하기 어려운 부분은 stub을 사용하여 테스트한다.
    • 비용이 크지 않다면 stub 보다는 실제 객체를 사용하는 것이 좋다.
    • 아무래도 정교한 목 객체가 실제 객체보다 정확하지는 않기 때문이다.
    • 모든 것은 비용 관점에서 생각해야 한다.

정리

유닛 테스트는 어떠한 부분에 문제가 있고 고칠 부분이 어디인지 명확하게 해 줄 때 좋다.
테스트 중심 개발(test-driven development) 일 때 유닛 테스트는 꼭 작성해야 하며, 코드의 디자인을 개선해주고 나중에 코드의 리팩토링이 필요할 때 어떤 부분을 완전히 분리할 필요 없이 깔끔하게 해 준다.

✨ Integration Testing

다른 모듈이 그룹으로 결합될 때 잘 작동하는지 확인하는 것이다.

  • 모듈을 통합하는 과정에서 모듈 간 호환성의 문제를 찾아내기 위해 수행되는 테스트이다.
  • 유닛 테스트와의 차이점은 유닛 테스트는 다른 컴포넌트들과 독립적인 반면 통합 테스트는 그렇지 않다.
  • 예를 들면, 유닛 테스트에서 데이터베이스에 접근하는 코드는 실제 데이터 베이스와 통신하는 것은 아니지만, 통합 테스트는 실제 통신해야 한다.
  • 통합 테스트는 대게 유닛 테스트를 작성하는 것보다 복잡하고 오랜 시간이 걸린다.
    👉 데이터베이스를 세팅할 때, 설정 파일을 읽어 오는 과정
    👉 데이터베이스가 잘 세팅되었는지 확인하는 과정
  • 꼭 필요한 것이 아니라면, 유닛 테스트를 작성하는데 집중하는 것이 좋다.

✨ Functional Testing

사용자와 어플리케이션의 상호작용이 원활하게 이루어지는지 테스트하는 것이다.

기능 테스트는 통합 테스트와 관련이 있지만, 모든 코드가 함께 실행되는 상태에서 전체 애플리케이션의 기능을 확인하는 테스트를 의미한다.
👉 어떤 웹 어플리케이션을 기능 테스트한다고 가정해보면 브라우저 자동화 도구를 사용해 특정한 페이지를 클릭하는 것

특징

  • 해당 시스템과 해당 시스템을 구축하고 배포하는 프로세스를 모두 시험하는 것을 말합니다.
    • 회원 가입과 같이 브라우저에서 앱의 특정 흐름을 수동으로 테스트하는 경우
      👉 유저가 회원가입을 마치고 "저희 사이트에 회원 가입하게 된 것을 축하드립니다."라는 페이지를 올바르게 출력해줄 것을 보장해주어야 한다.
  • 내부 기능들까지(클래스의 메서드) 테스트 할 필요는 없습니다.
    • 이는 단위테스트의 영역입니다.
  • 단점은 테스트를 만들기가 힘들고, 만든 테스트를 신뢰하기도 힘들다는 것입니다.

✨ Stub / Mock

단위 테스트는 해당 모듈에 대한 독립적인 테스트이기 때문에 다른 객체와 메세지를 주고 받는 경우에 문제가 발생하며 이때 사용하는 것이 stub와 Mock이다.

Stub

stub은 아직 준비되지 못한 코드를 미리 정해진 답변으로 반환할 수 있도록 하는 메커니즘입니다. 가짜 객체가 실제로 동작하는 것처럼 보이게 만들어놓은 객체이며, 호출자를 실제 구현물로부터 격리시켜 독립적인 테스트를 진행할 수 있도록 하는 것이 Stub입니다.

  • 복잡한 로직을 단순화 하고 싶을 떄
  • 구현이 되지 않은 함수가 있을 때
  • 라이브러리에서 제공하는 함수를 사용하고자 할 때
  • 의존성을 가지는 유닛의 응답을 모사하여 독립적인 테스트를 수행하고자 할 때

Mock

Mock은 가짜라는 의미인데, 이 Mock 이 사용되는 부분은 Mocking이라는 작업을 할 때 사용한다.

Mocking이란, 유닛 테스트 등을 작성할 때 해당 코드가 의존성을 가지고 있다면 그 의존하는 부분을 가짜로 대체하는 기법입니다. 일반적으로 유닛 테스트의 해당 코드가 의존하는 부분을 직접 생성하는 것이 까다로울 때 Mocking을 많이 사용합니다.

예를 들어 데이터베이스에 새로운 데이터를 추가하는 코드를 테스트한다고 하면, 가짜 데이터베이스(Mock Database)를 주입하여 insert 처리 시에 반드시에 1을 반환하도록 해주는 것이 stub이다.


✨ Good Unit Test

❗️ 실제 코드를 변경한다는 것은 잠재적인 버그를 일으킬 수 있다 ❗️

때문에, 좋은 테스트 코드가 있다면 변경된 코드를 검증함으로써 이를 해결해야 한다.

❗️ 실제 코드가 변경되면 테스트 코드 역시 변경이 필요할 수 있다 ❗️

테스트 코드 역시 가독성있게 작성해야 한다.

  • 1개의 테스트 함수에 대해 assert를 최소화하기
  • 1개의 테스트 함수는 1가지 개념 만을 테스트하기

✅ FIRST

  • Fast
    테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.

  • Independent
    각각의 테스트는 독립적이며 서로 의존해서는 안된다.

  • Repeatable
    어느 환경에서도 반복 가능해야 한다.

  • Self-Validating
    테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증되어야 한다.

  • Timely
    테스트는 적시에 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.


📚 학습할 때, 참고한 자료 📚

profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글