LikeTech Main.

Unit test, Integration test, Functional test

Jihoon Na
Jihoon Na

Introduction

오늘은 unit test, integration test, E2E(End to End) test에 대해서 알아보겠습니다. 대부분의 회사에서 CI/CD(지속적 통합/개발)를 통해 제품을 관리하고 있기때문에 개발 조직에서의 테스트의 중요성이 점차 증가하고 있습니다. 오늘은 테스트에 대한 내용 중 위의 3가지 내용에 대해서 살펴볼 예정입니다(Spring framework와 Spock 예시 이용). 시작하기에 앞서 3가지 개념에 대한 정의를 알아보고 가겠습니다.

Unit test

In computer programming, unit testing is a software testing method by which individual units of source code—sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures—are tested to determine whether they are fit for use. ref) Wiki

Integration test

Integration testing (sometimes called integration and testing, abbreviated I&T) is the phase in software testing in which individual software modules are combined and tested as a group. Integration testing is conducted to evaluate the compliance of a system or component with specified functional requirements. ref) Wiki

E2E test

End-to-end testing is a technique that tests the entire software product from beginning to end to ensure the application flow behaves as expected. ref)Katalon home page

Contents

글보다는 그림을 보는 것이 더 기분이 좋기 때문에 먼저 그림을 하나 보도록 하겠습니다.

diagram

우리가 오늘 살펴볼 3가지 테스트에 대한 그림입니다. 피라미드의 상층부로 갈수록 더욱 비싸고 오래걸리는 테스트이고 아래로 갈수록 더욱 저렴하고 빠르게 수행할 수 있는 테스트입니다. 피라미드 형태인 이유는 케이스 자체는 유닛테스트가 제일 많고 e2e test가 적기 때문에 이런식으로 표현을 하였습니다.

위의 정의에 따르면 단위 테스트는 소스 코드의 개별적인 부분에 대한 테스트이고, 통합 테스트는 그룹으로서 테스트 되는 것을 의미, 마지막으로 E2E 테스트는 제품에 대한 전체 테스트를 의미한다고 합니다. 역시 그냥 정의를 봐서는 잘 이해가 되지 않기 때문에 바로 예시로 넘어가도록 하겠습니다.

만년 신입 나신입 사원은 드디어 자신이 열심히 개발하던 프로젝트 오픈을 앞두고 있습니다. 이번에 그의 회사에서 개발한 제품은 아래와 같습니다. 이름은 최고의 계산기... 가지고 있는 돈을 넣으면 현재의 환율에 따라 달러의 가치로 계산을 해주는 그런 계산기입니다. 그는 팀장님에게 오픈전 마지막 시연을 하게되었습니다.

diagram

나신입 사원 : 이번에 저희 팀에서 런칭할 제품인 최고의 계산기입니다. 최고의 기술이 적용되었고 최신 트렌디한 색상의 버튼과 ~.
(그의 유창한 발표에 모든 사람들은 감동에 빠지고..)
너사장 사장 : 아주 좋군요 나신입 사원. 정말 다 좋은데, 지난 번에 우리 배포 나가고 버그 발견되어서 망신 당한거 알죠~?
너사장 사장 : 이번엔 그런일 없도록 `단위 테스트`, `통합 테스트`, `e2e 테스트` 등 잘 진행되고 있는 거 맞죠?
나신입 사원 : 네! (그는 그게 뭔진 몰랐지만 자신감 넘치게 대답한다.)

자리에 돌아온 나신입 신입은 자신의 순간 기억능력으로 기억나는 단어들을 적어내린다.. 단위 테스트... 이투위 테스트? 통합테스트...

소스 코드의 개별적인 부분을 테스트 한다라...


public class Calculator {

    public static BigDecimal getUsdFromWon(BigDecimal won, BigDecimal exchangeRate){
        return won/exchangeRate;
    }

}

먼저 유닛테스트부터 작성해봐야겠어.. 우리가 제일 핵심 기능인 환율을 통해 달러를 계산하는 함수부터 테스트를 작성해보자!


class CalculatorUnitTest extends Specification {
def "calculatorTest"() {
expect:
expected == Calculator.getUsdFromWon(inputWon, exchangeRate)

        where:
        inputWon       | exchangeRate    | expectedUsd
        1200           | 1200            |      1
        2400           | 1200            |      2
    }

}

단위 테스트 어렵지 않은데~? 좋아 이번엔 그 integration 테스트를 한번 해보자! 통합 테스트라.. 작은 단위의 테스트 말고 좀 더 큰 그룹의 테스트라 이거지? 그렇다면 이 환율 계산기 단위가 아닌 상위에서 db의 환율 정보를 받아와 계산하는 것을 한번 진행해보자!


public class CalculatorService {
private final ExchangeRateDao exchangeRateDao;

    public BigDecimal getUsdFromWon(BigDecimal won){
        return Calculator.getUsdFromWon(won, exchangeRateDao.getExchangeRate());
    }

}

좋아 서비스 레이어에서 dao를 통해서 환율 정보를 받아와서 실제 계산을 하고 있으니까 여기에 있는 함수를 테스트 해보겠어! 그럼 서비스 레이어를 이용해야하니까 실제 스프링을 구동시켜서 DI가 작동하도록 해야하니, @SpringBootTest annotation을 사용하면 되겠다!


@SpringBootTest(classes = Application.class)
class CalculatorServiceIntegrationTest extends Specification {

    @Autowired
    private final CalculatorService calculatorService;

    def "calculatorServiceTest"() {

        expect:
        expected == calculatorService.getUsdFromWon(inputWon)

        where:
        inputWon       | expectedUsd
        1200           |      1
        2400           |      2
    }

}

오호~ 이렇게 더 큰 단위로 테스트 하는게 바로 integration 테스트구나~ 좋아 이런식으로 진행하면 되는거군. 이제 마지막으로 e2e 테스트다!

diagram

우선.. 해당 url에 접속 했을 때 페이지는 잘 뜨고.. 그리고.. 숫자 입력 잘되고 버튼 잘 눌리고 ... E2E test 끝!! (나신입 사원은 기쁜 마음으로 퇴근하였습니다~)

Result

이처럼 제품 오픈에 앞서 QA를 거치기 전에 개발 조직에서 테스트를 진행할 때 사용하는 단어들에 대해서 살펴보았습니다.

오늘의 내용 요약 : 유닛 테스트, 통합 테스트, e2e 테스트에서 알아보았습니다.

수고하셨습니다!