22.04.11 WIL testing

Seunghan·2022년 4월 12일
0

Spring

목록 보기
2/2

개발에 있어서 테스트의 중요성은 매우 잘 알려져 있다. 테스트를 작성한다는 행위의 의미를 잘 파악하고 테스트 주도 개발(Test-Driven-Develop)를 의도적으로 실시하자!

Testing Level

테스트 레벨 위키피디아

Test Pyramid

기능테스트, End-to-end 테스트를 수행하려면 브라우저나 모바일 입과 같은 클라이언트부터 DB까지 모든 환경이 갖춰져야 하기 떄문에 자동화하거나 다양한 상황별로 테스트하기 어렵다. 그러므로 정상적인 경우와 몇 가지 특수한 상황만 테스트 범위로 잡는다.

통합 테스트는 기능 테스트에 비해 제약이 덜하다

https://martinfowler.com/bliki/TestPyramid.html

단위테스트는 빠르고 간단하다.

단위 테스트에서 다양한 상황을 다루고, 통합테스트나 기능 테스트는 주요 상황에 초점을 맞추어야 한다.

코드의 양

단위 테스트 > 통합 테스트 > 기능 테스트

https://martinfowler.com/articles/microservice-testing/#conclusion-test-pyramid

https://martinfowler.com/articles/microservice-testing/#conclusion-summary

단위 테스트(Unit Test)

개별 모듈이 제대로 구현되어 정해진 기능을 정확히 수행하는지를 테스트하는 것

화이트박스 테스트와 블랙박스 테스트를 모두 사용할 수 있지만, 모듈 내부를 구체적으로 들여다 볼 수 있는 화이트박스 테스트같은 구조적 테스트를 주로 실시한다.

단위테스트가 개발된 모듈만 테스트한다고 생각하기 쉽지만, 단위 테스트를 통과하기 위해서는 그 모듈과 직접 관련된 상위 모듈과 하위 모듈까지 모두 존재하고, 각각의 모듈이 정상적으로 작성해야 테스트 통과 할 수 있다.

→ 단위 테스트를 잘 작성하는 것이 핵심!

성공 케이스, 실패(엣지)케이스 계속해서 생각하며 무수한 공격을 방어해야 한다.

단위 테스트는 ApplicationContext와 상호 작용해서 끌어오고 복잡하게 구성하지 말고 하나의 클래스의 기능에 집중해서 단위테스트를 구성하도록 하자

단위 테스트를 진행하는 목적

  • 소프트웨어의 요구사항은 계속해서 변경된다.

코드를 변경하더라도 테스트 코드에 의해 기존의 기능이 작동 한다는 것을 보장할 수 있다.(기존의 코드가 보호된다)

  • 테스트 코드가 있으면 구현 코드를 일일히 읽어보지 않아도 흐름 또는 어떤 기능을 제공하는지 쉽게 파악할 수 있다.

    +) End-to-end test, Contract test들과 같은 복잡한 테스트의 경우 QA 엔지니어가 테스트를 작성하는 경우가 많다.
    백엔드 엔지니어는 단위 테스트를 가장 많이 작성한다.

Junit에 대하여

  • 매 단위 테스트시마다 테스트 클래스의 인스턴스가 생성되어 독립적인 테스트가 가능하게 한다.
  • 어노테이션을 제공해서 테스트 라이프 사이클을 관리하게 해주고 테스트 코드를 간결하게 작성하도록 지원한다.
  • 테스트 러너를 제공해서 Intellij/ Eclipse/ Maven 등에서 테스트 코드를 쉽게 실행하게 해준다.
  • assert로 테스트 케이스의 수행 결과를 판별하게 해준다 - 주로 값 비교

Junit4

junit.jar 단일 모듈로 존재

확장성이 매우 떨어지는 문제가 있었다.

Junit5

JUnit Platform

JVM상에서 테스팅 프레임워크를 런칭하기 위한 근간 제공, TestEngine을 통해서 테스트를 발견하고, 실행하고, 결과를 보고

TestEngine 인터페이스 : 테스트를 발견하고 테스트 계획 생성

JUnit Jupiter

Jupiter-engine은 TestEngine의 실제 구현체 중 하나. Jupiter-api를 사용해서 작성한 테스트 코드를 발견하고 실행하는 역할을 한다.

Jupiter API는 JUnit5 에 새롭게 추가된 텟트 코드용 API로서, 개발자는 Jupiter API를 사용해서 테스트 코드를 작성할 수 있다.

JUnit Vintage

기존의 JUnit4 버전으로 작성한 테스트코드를 실행할 때 vintage-engine 모듈 사용

Mock Object(모의 객체)

테스트를 작성하다 보면 외부 요인이 필요한 시점이 있다.

  • 테스트 대상에서 파일 시스템을 사용
  • 테스트 대상에서 DB로부터 데이터를 조회하거나 데이터를 추가
  • 테스트 대상에서 외부의 HTTP 서버와 통신

→ 외부에서 기능을 제공하지 않으면 테스트를 진행할 수 없게 된다.

즉 외부 요인은 테스트 작성을 어렵게 만들 뿐만 아니라 테스트 결과도 예측할 수 없게 만든다.

외부에 의존하는 요인 때문에 테스트가 어려울 때는 대역(test double)을 써서 테스트를 진행하자!

테스트 더블(Test double)

테스트를 진행할 때 해당 모듈은 다른 모듈(협력 관계자)들과 의존관계를 가지게 된다.

테스트 더블(Test double)은 의존 구성요소를 사용할 수 없을때( 준비되지 않았거나 연결에 문제가 있을 때 ) 테스트 대상 코드와 상호작용하는 객체를 만들어 대체해서 SUT만의 고립된 테스트를 진행하는 것이다.

SUT(System Under Test) : 시스템에서 제공해주는 기능들을 테스트

Mock을 위한 Test framework

  • Mockito - 주로 사용
  • JMock
  • EasyMock

대역 종류

스텁(Stub)구현을 단순한 것으로 대체. 테스트에 맞게 단순히 원하는 동작을 수행
가짜(fake)제품에는 적합하지 않지만, 실제 동작하는 구현을 제공 ex) MemoryAutoDebitInfoRepository
스파이(Spy)호출된 내역을 기록. 기록한 내용은 테스트 결과를 검증할 때 사용
모의(Mock)기대한 대로 상호작용하는지 행위를 검증. 기대한 대로 동작하지 않으면 exception 발생. 모의 객체는 Stub이자 Spy도 된다.

Hamcrest

장점

  • SpringBoot에서 지원. 의존성을 추가하지 않고 사용할 수 있다.
  • 가독성이 좋다.
assertThat(theBiscuit, is(myBiscuit));
  • Collection을 테스트할 수 있는 기능을 많이 제공해준다.

    Hamcrest Tutorial

    UUID - 범용 고유 식별자

    범용 고유 식별자(汎用固有識別子, 영어: universally unique identifier, UUID)는 소프트웨어 구축에 쓰이는 식별자 표준으로, 개방 소프트웨어 재단(OSF)이 분산 컴퓨팅 환경(DCE)의 일부로 표준화하였다.

    UUID는 16 옥텟 (128비트)의 수이다. 표준 형식에서 UUID는 32개의 십육진수로 표현되며 총 36개 문자(32개 문자와 4개의 하이픈)로 된 8-4-4-4-12라는 5개의 그룹을 하이픈으로 구분한다. 이를테면 다음과 같다.

550e8400-e29b-41d4-a716-446655440000

340,282,366,920,938,463,463,374,607,431,768,211,456개의 사용 가능한 UUID가 있다.

profile
주니어 백엔드 개발자입니다!

0개의 댓글