본문 바로가기
Study/Java

[Java] TDD 톺아보기

by dev_kong 2022. 11. 3.
728x90
728x90

수정과 지적 환영합니다. 막 대해 주세요.

0. 목차

1. 개요

2. TDD란?

3. 테스트 코드 작성

4. 정리

1. 개요

우테코 2주차 미션에 JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을 테스트 코드로 확인한다 . 라는 내용이 추가되었다.
JUnit 5AssertJ가 누구신지는 모르겠지만,
대충 TDD 해라 라는 내용인건 확실하다.

 

이렇게 말하면 내가 TDD에 대해 잘 알고, 잘하는 사람 처럼 보이겠지만 초면이다.

그냥 어디서 주워들은게 있다.
작업을 하기전에 TDD가 무엇인지, 어떻게 하는 건지 하나하나 톺아보려한다.

2. TDD란?

TDD의 뜻은 Test Driven Development 의 약자이다. 소중한 우리말로는 테스트 주도 개발 이다.
음 항상 용어만 봐서는 뭔지 감도 안잡힌다.

 

위키에서 TDD를 검색해보면 아래와 같은 내용이 나온다.
테스트 주도 개발(Test-driven development TDD)은 매우 짧은 개발 사이클을 반복하는 소프트웨어 개발 프로세스 중 하나이다. 개발자는 먼저 요구사항을 검증하는 자동화된 테스트 케이스를 작성한다. 그런 후에, 그 테스트 케이스를 통과하기 위한 최소한의 코드를 생성한다. 마지막으로 작성한 코드를 표준에 맞도록 리팩토링한다.

 

천천히 읽어보면 TDD의 작업 순서는 아래와 같다는 것을 확인 할 수 있다.

  1. 테스트 코드 작성
  2. 테스트 코드를 통과하기 위한 최소한의 코드 작성
  3. 테스트 코드 통과를 유지하면서 리팩토링

그림으로 보면 아래와 같다.


Red가 위 내용의 1번
Green이 2번
Blue가 3번에 해당된다.

2-1. 테스트 도구 JUnit

대충 어떻게 하는 건지는 느낌이 온다.


테스트 코드는 그럼 어떻게 작성하는 걸까.
테스트 코드를 작성하기위해선 테스트 도구(=프레임워크) 가 필요하다.


각 언어마다 TDD를 담당하는 프레임워크가 있다.
Java는 JUnit을 사용하고, Javascript는 Jest를 사용한다.

사랑했다 자바스크립트...


첫번째 궁금증이었던, JUnit에 대해 알게되었다.
결론은 JUnit은 Java 프로그램의 단위 테스트를 위한 테스트 도구 이다.

2-2. AssertJ

아직 남은 궁금증 한가지 AssertJ.


TDD에 대해 검색해보면 JUnit까진 같이 딸려 나오는데
이 친구는 같이 안나오더라.


대충 느낌적으로 TDD를 하기 위해서 꼭 필요한 아이가 아닌,
부가적인 친구인듯하고, 우테코에서는 이 친구의 사용을 지향하는 듯 하다.


그러므로 AssertJ에 대해 자세히 작성은 안할거임.ㅎ
대신 누가 정말 정리가 잘되어있는 블로그 발견해서 그거 링크만 추가해놓겠다.

https://pjh3749.tistory.com/241

 

[AssertJ] JUnit과 같이 쓰기 좋은 AssertJ 필수 부분 정리

AssertJ가 core document를 새로운 github.io로 이전했네요 :) . 본 글은 AssertJ 공식 문서를 핵심 챕터를 선정하여 번역하며 정리한 글 입니다. http://joel-costigliola.github.io/assertj/assertj-core.html AssertJ란 무엇인

pjh3749.tistory.com

(근데 달려있는 댓글 보니까 우테코 출신같음.. 센빠이..?)

 

대충 요약하자면,
Java 테스트에서 유창하고 풍부한 assertions를 작성하는 데 사용되는 오픈 소스 커뮤니티 기반 라이브러리이고,
JUnit에도 assertions를 작성하는 기능이 기본적으로 탑재되어 있지만,
AssertJ가 가독성이나 활용도면에서 더 뛰어나다.
라는 내용이다.

3. Test Code 작성

이제 이론은 완벽하다.

실전으로 들어가 보자

음 프리코스 1주차 1번 문제중에 세자리 숫자가 주어지면 각각의 합과 곱을 구해 큰 수를 리턴하는 문제가 있었는데,
그걸 간단한게 테스트코드 작성을 통해 해볼까 한다.

3-1. Red

TDD에선 코드작성의 순서가 테스트코드부터 작성한다고 했다.
테스트 코드부터 작성을 해보자.

 

public class MaxValueTest {

    @Test
    void check_max_value_test() {
        // 내용 작성하면 됨 
    }
}

 

우선 틀만 잡았다.
test code의 class 명은 test할 class이름 + Test 가 국룰이다.
@Test 메소드가 호출 될때 마다 새로운 인스턴스를 생성해서 독립적인 테스트를 수행하도록 해준다.


메소드 명은 언더바를 쓰던데.. 궁금해서 찾아보니 논리적으로 해석될 수 있는 단위로 언더바를 사용해서 네이밍한다고 한다..
무슨 말인지는 모르겠고 그냥 따라해봤다.. 하다보면 깨우칠 날이 오지 않을까.

 

이제 내용을 작성해보자.

 

@Test
void check_max_value_test() {
    Integer input = 234;
    Integer expect = 24;
    Integer result = maxValue(input);

    Assertions.assertThat(result).isEqualTo(expect);
}

 

이렇게만 하면 된다.


input의 값이 메소드의 param으로 들어갈 값이고,
expect는 기대값이다.
result는 메소드의 리턴값을 할당해주고


마지막 assertions를 작성해주면 된다.

3-2. Green

이번엔 위의 테스트를 통과할 수 있도록 메소드를 작성해보자.

    public static Integer maxValue(Integer number) {
        int sum = 0;
        int multiple = 1;
        String string = Integer.toString(number);

        for (int i = 0; i < string.length(); i++) {
            int targetNumber = Integer.parseInt(string.substring(i, i + 1));
            sum += targetNumber;
            multiple *= targetNumber;
        }

        return Math.max(sum, multiple);
    }

이렇게 코드를 작성하면 위에서 작성한 테스트를 통과하는 것을 확인할 수 있다.

3-2. Blue

테스트는 통과했으나,
위의 코드 상당히 비효율 적이다.


숫자를 받아서 스트링으로 변환시켜서,
그걸 포문을 돌아서 substring으로 잘라서,
그걸 다시 Integer로 변환해서 연산을 한다.


미친 코드다.

이제 이걸 리팩토링해보자.

    public static Integer maxValue(Integer number) {
        int sum = 0;
        int multiple = 1;

        while(number>0){
            int target = number % 10;
            sum += target;
            multiple *= target;
            number /= 10;
        }

        return Math.max(sum, multiple);
    }

while을 통해 깔끔하게 해결 가능하다.

4. 결론

음.
TDD 말만 들어봤지 해보는건 처음이다.


현재 프리코스 2주차를 진행하면서 TDD를 하고 있긴한데,
직접 해보니까 느껴지는게 있다.


귀찮다. 하지만 확실하다.
게다가 디버깅이 매우 편하다 진짜로.
실보다는 득이 훨씬 많긴 하다.
특히나 로직이 복잡한 무언가를 한다거나,
기능 구현을 하면서 '이거.. 이렇게 하는게 맞나..?' 싶은 부분에 대해선 확실하게 성능 보장한다.

하지만 TDD에 대한 내용을 조금만 검색해보면,
이거 왜하냐. 당장 기능 구현 하기도 바빠 죽겠는데 무슨 테스트 코드냐.
실용성 떨어진다.
라는 얘기들도 많이 나온다.


실제로 코드작성량이 늘어나는 것은 사실이니까,
빨리빨리 결과물을 쳐내야 하는 회사에서는 TDD문화가 자리잡긴 힘들 것이다

.

어느정도 절충안을 잡자면,
현재는 TDD가 처음이라 모든 기능에 테스트코드를 작성하면서 하고있다.
하지만 어느정도 익숙해지면, 결과가 당연한 것들에 대해서는 굳이 작성할 필요가 없는거 아닌가 라는 생각도 든다.
뭐 예를 들어 숫자 두개 더해서 결과값 리턴하는 함수를 작성 할 때는 테스트코드가 필요없듯이 말이다.


아직은 연습이 필요한 단계라 최대한 많은 테스트코드를 작성해보려고 노력하고 있다.
하루 빨리 익숙해지길.

 

혹시라도 누군가가 이글을 보고 잘못된점이 있다면 가차없이 지적해주면 좋겠다... 제발..

728x90
728x90

댓글