hayu's 개발 일지

[TIL]240415 테스트란 본문

프레임워크/spring

[TIL]240415 테스트란

hayu00 2024. 4. 15. 21:00

테스트 코드를 작성하는 이유?

  • 테스트 코드를 작성하면 비용을 절감할 수 있다.
  • 서버에서 실행해서 직접 테스트 해보지 않아도 되기 때문에 시간 단축이 가능하다.
  • 테스트 코드를 통해 어떤 값이 주어졌을 때(Given), 어떤 실행을 하면(When), 어떤 결과가 나와야 하는지(Then)를 확인할 수 있기 때문에 코드를 파악하는데도 도움이 된다.
  • → given - when - then
  • 수정사항이 발생하면 기존의 코드에 영향을 주는지 테스트 코드를 통해 파악할 수 있다.
  • 정확한 테스트 코드를 작성해 놓으면 실제 코드를 제대로 작성했는지 확인할 수 있다. (TDD : 테스트 주도 개발)

TDD(Test-Driven Development : 테스트 주도 개발)

  • TDD는 개발이 이루어진 다음 테스트 케이스 작성 및 테스트를 하는 것이 아닌, 테스트 케이스를 먼저 작성한 다음 테스트 케이스에 따라 실제 개발을 수행하는 방법이다.
  • 작은 단위의 기능을 테스트하고 작성하기 때문에 피드백 주기가 짧으며 코드가 변경되어도 테스트를 수행하여 기존 요구사항에 대한 영향을 파악하고 오류를 방지할 수 있다.

→ 코드의 품질이 향상되고 유지보수성이 좋아진다.

테스트의 종류

단위 테스트(Unit Test)

  • 소프트웨어의 가장 작은 단워인 모듈, 함수, 클래스 등의 개별적인 기능을 테스트 하는 것을 말한다.
  • 주로 프로그래머가 작성하며, 코드의 동작을 검증하고 예상대로 동작하는지 확인한다.
  • 코드 변경 시에 기존 코드의 충돌 및 오류를 발견 가능하며, 새로운 코드의 동작 성공 여부를 확인할 수 있다.
  • TDD에서의 테스트 케이스는 주로 단위 테스트 작성을 의미한다. 그리고 주로 자동화되어 사용된다.(CI)CD(Continuous Deployment : 지속적 배포) : CI를 통과한 이후, 자동화된 프로세스를 통해 테스트를 통과한 코드를 실제 환경으로 자동으로 프로덕션 환경에 배포하는 파이프라인 구축을 목적으로 한다.
  • CI(Continuous Integration : 지속적 통합) : 개발자들이 작업한 코드를 지속적으로 통합하여 통합 문제를 최소화하고, 코드 변경이 일어날 때마다 자동으로 빌드 및 테스트가 실행되며, 코드 베이스에 통합시키도록 한다.

장점 : 새로운 기능에 대해 빠르게 작성이 가능하다. / 테스트 코드 자체가 하나의 문서가 된다. / 시간과 비용이 절감된다.

단점 : 독립적인 테스트이기 때문에 다른 객체와 상호작용 처리를 위해서 가짜 객체 정의가 필요하다. / 가짜 객체의 답변 작성이 필요하다. / 실제 운영 환경과 다른 답변을 내놓을 수 있다.

통합 테스트(Integration Test)

  • 각각의 모듈이 제대로 상호작용하는지, 시스템의 구성 요소들이 올바르게 통합되어 동작하는지를 확인한다. 즉, 이름과 같이 독립적인 기능이 아닌, 모듈 간의 연계되어 동작하는 것을 확인하는 것이다.

장점 : 실제 객체를 사용하므로 가짜 객체를 사용하지 않아 정의하지 않아도 된다. / 실제 운영 환경과 같은 값을 도출 가능하다.

단점 : 테스트 하나의 많은 비용이 들어간다. / 문제 발생 시, 어느 계층에서 발생한 문제인지 파악이 힘들다.

단위테스트 작성 공통 준수 사항

  • Given/When/Then 패턴

Given(어떤 데이터가 주어질 때)

  • 테스트 하고자하는 대상을 실제로 실행하기 전에 테스트에 필요한 값(상태)을 미리 선언해 둔다.

When(어떠한 기능을 실행하면)

  • 테스트 하고자하는 대상을 실제로 실행시킨다.

Then(어떠한 결과를 기대한다.)

  • 어떤 특정한 행동(테스트 대상 실행)때문에 발생할거라고 예상되는 결과에 대해 예측하고 맞는지 확인한다.

예시 코드

class CalculatorTest {

    Calculator calculator;

    @BeforeEach
    void setUp() {
        calculator = new Calculator();
    }

    @Test
    @DisplayName("계산기 연산 성공 테스트")
    void test1() {
        // given
        int num1 = 5;
        String op = "/";
        int num2 = 2;

        // when
        Double result = calculator.operate(num1, op, num2);

        // then
        assertNotNull(result);
        assertEquals(2.5, result);
    }

    @Test
    @DisplayName("계산기 연산 실패 테스트 : 분모가 0일 경우")
    void test1_1() {
        // given
        int num1 = 5;
        String op = "/";
        int num2 = 0;

        // when
        Double result = calculator.operate(num1, op, num2);

        // then
        assertNull(result);
    }

    @Test
    @DisplayName("계산기 연산 실패 테스트 : 연산자가 잘못됐을 경우")
    void test1_2() {
        // given
        int num1 = 5;
        String op = "?";
        int num2 = 2;

        // when - then
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> calculator.operate(5, "?", 2));
        assertEquals("잘못된 연산자입니다.", exception.getMessage());
    }
}

 

참고 자료

- https://velog.io/@sussa3007/Spring-JUnit-Mockito-%EA%B8%B0%EB%B0%98-Spring-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1

- https://dingdingmin-back-end-developer.tistory.com/entry/Springboot-Test-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1-1

- https://sjh9708.tistory.com/195

- https://chb2005.tistory.com/63