JUnit in Action : 1. JUnit 첫걸음

    들어가기 전

    이 글은 JUnit in Action 1장을 공부하며 정리한 글입니다. 


    1.2 밑그림부터 시작하기 

    여기서는 왜 테스트 프레임워크가 필요한지에 대해서 알아보는 과정이다. 

    public class Calculator {
        public double add(double n1, double n2) {
            return n1 + n2;
        }
    }

    위 클래스가 존재한다.

    • 컴파일 시, 문법 오류가 없다는 것은 바로 알 수 있다.
    • 위 메서드가 제대로 동작하는지는 알 수 없다. 

    add() 메서드가 정상적으로 동작하는 것을 보장하기 위해서 새로운 Test 클래스를 작성해야한다. 이에 대응되는 Test 클래스를 작성하면 가장 기본적인 코드는 아마 이렇게 될 것이다.

    public class CalculatorTest {
        public static void main(String[] args) {
            Calculator calculator = new Calculator();
            double result = calculator.add(10, 50);
            if (result != 60) {
                System.out.println("Bad result : " + result);
            }
        }
    }

    기초적으로 작성한 위 테스트 코드는 실행하자마자 한 가지 문제점이 발생한다. 바로 테스트 결과를 개발자가 직접 확인해야한다는 것이다.

    • Bad Result가 나오는지 / 안 나오는지를 확인해야한다. 

    이런 문제를 어떻게 개선할 수 있을까? 자바에서는 오류가 발생했을 때 Exception을 던진다. 따라서 테스트 코드의 개선 방향도 '원하는 결과가 나오지 않았을 때 에러를 던진다'라는 방향으로 잡을 수 있다. 그렇게 개선한 코드를 작성하면 다음과 같다.

    public class CalculatorTest2 {
    
        private int failCount = 0;
        
        public void testAdd() {
            Calculator calculator = new Calculator();
            double result = calculator.add(10, 50);
            if (result != 60) {
                throw new IllegalStateException("Bad result : " + result);
            }
        }
        
        public static void main(String[] args) {
    
            CalculatorTest2 test = new CalculatorTest2();
            try {
                test.testAdd();
            } catch (IllegalStateException e) {
                test.failCount++;
                e.printStackTrace();
            }
    
            if (test.failCount > 0) {
                throw new IllegalStateException("There were" + test.failCount + " error(s)");
            }
        }
    }

    코드는 다음과 같이 작성했다.

    • 테스트 로직을 testAdd()라는 전용 메서드로 분리했다. 
    • 메인 메서드에서 여러 테스트 로직을 메서드 단위로 실행할 수 있도록 작성했다.

    위의 내용에서 테스트 클래스를 하나 만들고, 단위 테스트를 작성하고 그 테스트를 실행하는 메인 클래스를 생성해야한다는 것으로 정리할 수 있다.

     


    1.3. 단위 테스트 프레임워크 이해하기

    위 코드에서 작성한 내용은 개발자가 직접 작성해야하는 부분이다. 그런데 이런 분들은 매번 반복되고 공통되는 부분이기 때문에 하나로 추상화 할 수 있다. 이렇게 추상화 된 프레임워크를 단위 테스트 프레임워크로 이해할 수 있다. 각각의 단위테스트는 아래 세 가지 규칙을 따를 것을 강조한다. 

    • 단위 테스트는 다른 모든 단위 테스트들과 독립적으로 실행되어야 한다.
    • 프레임워크는 테스트 각각의 오류를 식별하고 보고해야 한다.
    • 어떤 테스트를 실행할지 선택하기 쉬워야 한다. 

    위에 작성한 코드에서 새로운 테스트 코드를 추가하는 방법은 try ~ catch 블록을 하나 추가하는 것이다. 그런데 이 경우 유지보수에 문제가 있다. 이런 문제들 때문에 개발자가 직접 테스트 프레임워크를 작성하기 보다는 테스트 프레임워크를 사용하는 것이 좋다. 

    테스트 프레임워크는 테스트 메서드를 새로 추가하기만 하면 알아서 실행되도록 한다. 이런 기능은 Java의 리플렉션과 인트로스펙션 기능을 활용하는 방법이 있다. Junit은 이 기능을 제공하기 위해 인트로스펙션 방식을 제공한다. Junit은 고유한 클래스 인스턴스와 클래스 로더 인스턴스를 사용하며, 테스트 별로 에러 결과를 알려준다. 

     


    1.6 Junit으로 테스트 코드 실행하기

    위에서 작성한 테스트 클래스를 JUnit을 이용하면 아주 손쉽게 구현할 수 있다. 

    public class CalculatorTest {
        @Test
        public void testAdd() {
            Calculator calculator = new Calculator();
            double result = calculator.add(10, 50);
            Assertions.assertEquals(60, result, 0);
        }
    }

    Junit을 이용한 테스트 코드를 작성할 때는 다음을 주의하면 된다

    • 테스트 클래스는 반드시 public으로 작성해야한다. 클래스 이름은 일반적으로 Test로 끝난다.
    • 테스트 메서드는 @Test 어노테이션을 붙여준다. Junit은 @Test 어노테이션을 기반으로 실행할 메서드를 찾는다. 

     

     


    1.7 정리

    • 제대로 동작하는지를 확인하기 위해서는 기능 테스트가 필요하다. 이것을 단위 테스트 프레임워크인 JUnit을 이용해 자동화 할 수 있다.
    • 개발자는 테스트 결과를 눈으로 직접 확인하지 않고, Junit이 판단하도록 한다.
    • 단위 테스트는 다른 모든 단위 테스트들과 독립적으로 실행되어야 한다.
    • 단위 테스트의 모토는 '프로그램에서 자동화된 테스트를 거치지 않은 기능은 존재하지 않는다'이다.

    댓글

    Designed by JB FACTORY