소스코드를 구현한 후 정상적으로 동작하는지 확인하는 일반적인 방법은 main() 메서드를 활용해 의도한 결과 값이 정상적으로 출력되는지 콘솔을 통해 확인하는 것이 일반적이다. 이 과정을 살펴보기 위해 덧셈(add), 뺄셈(subtract), 곱셈(multiply), 나눗셈(divide) 을 구현하는 간단한 사칙연산 계산기 구현 코드를 살펴본다.
public class Calculator {
int add(int i, int j) {
return i + j;
}
int subtract(int i, int j) {
return i - j;
}
int multiply(int i, int j) {
return i * j;
}
int divide(int i, int j) {
return i / j;
}
public static void main(String[] args) {
Calculator cal = new Calculator();
System.out.println(cal.add(3, 4));
System.out.println(cal.subtract(5, 4));
System.out.println(cal.multiply(2, 6));
System.out.println(cal.divide(8, 4));
}
}
계산기 코드는 실제로 서비스를 담당하는 프로덕션 코드(production code)와 이 프로덕션 코드가 정상적으로 동작하는지 확인하기 위한 main() 메서드로 나뉜다. 일반적으로 main() 은 프로그래밍을 실행하기 위한 목적과 프로덕션 코드가 정상적으로 동작하는지 확인하는 테스트 목적으로 나뉜다. 이 책에서는 main() 의 목적을 테스트로 생각해 테스트 코드로 부르도록 하겠다.
위 계산기 코드의 첫 번째 문제점은 프로덕션 코드와 테스트 코드(main() 메서드)가 같은 클래스에 위치하고 있다는 것이다. 테스트 코드의 경우 테스트 단계에서만 필요하기 때문에 굳이 서비스하는 시점이 같이 배포할 필요가 없다.
이 문제를 해결하기 위한 첫 번째 단계로 프로덕션 코드(Calculator 클래스)와 테스트 코드(CalculatorTest)를 분리할 수 있다.
public class Calculator {
int add(int i, int j) {
return i + j;
}
int subtract(int i, int j) {
return i - j;
}
int multiply(int i, int j) {
return i * j;
}
int divide(int i, int j) {
return i / j;
}
}
public class CalculatorTest {
public static void main(String[] args) {
Calculator cal = new Calculator();
System.out.println(cal.add(9, 3));
System.out.println(cal.subtract(9, 3));
System.out.println(cal.multiply(9, 3));
System.out.println(cal.divide(9, 3));
}
}
테스트를 담당하는 별도의 클래스를 추가했지만 main() 메서드 하나에서 프로덕션 코드의 여러 메서드를 동시에 테스트하고 있기 때문에, 프로덕션 코드의 복잡도가 증가할수록 main() 메서드의 복잡도도 증가하고 결과적으로 main() 메서드를 유지하는데 부담된다. 이 같은 문제를 해결하기 위해 다음과 같이 테스트 코드를 각 메서드별로 분리할 수도 있다.
public class Calculator {
int add(int i, int j) {
return i + j;
}
int subtract(int i, int j) {
return i - j;
}
int multiply(int i, int j) {
return i * j;
}
int divide(int i, int j) {
return i / j;
}
}
public class CalculatorTest {
public static void main(String[] args) {
Calculator cal = new Calculator();
add(cal);
subtract(cal);
multiply(cal);
divide(cal);
}
private static void add(Calculator cal) {
System.out.println(cal.add(9, 3));
}
private static void subtract(Calculator cal) {
System.out.println(cal.subtract(9, 3));
}
private static void multiply(Calculator cal) {
System.out.println(cal.multiply(9, 3));
}
private static void divide(Calculator cal) {
System.out.println(cal.divide(9, 3));
}
}
하지만 이 또한 최정적인 해결책이 될 수 없다. 그 이유는 개발자가 프로그래밍하는 과정을 살펴보면 된다. 프로그래밍을 할 때 한 번에 메서드 하나의 구현에 집중한다. 클래스가 가진 모든 메서드에 관심이 있는 것이 아닌 현재 구현하고 있는 메서드에만 집중하고 싶다. 하지만 위 테스트 코드는 Calculator 클래스가 가진 모든 메서드를 테스트할 수밖에 없다. 그렇다고 테스트하는 메서드만 남기고 다른 메서드를 주석처리 하는 것 또한 불합리한 작업이다.
main() 메서드를 활용한 위 테스트가 안고 있는 다른 문제점은 테스트 결과를 매번 콘솔에 출력되는 값을 통해 수동으로 확인해야 한다. 위와 같이 로직이 간단한 경우는 결과 값을 쉽게 예측하지만, 로직의 복잡도가 높은 경우, 구현을 완료한 후 한달이 지난 시점이라고 생각할 때, 프로덕션 코드의 복잡한 로직을 머릿속으로 계산해 결과 값이 정상적으로 출력되는지 일일이 확인해야 하는 번거로움이 있다.
main() 메서드를 활용한 테스트의 이 같은 문제점을 핵멸하기 위해 등장한 라이브러리가 JUnit 이다. JUnit 은 관심을 가지는 메서드에 대한 테스트만 가능하다. 또한 로직을 실행한 후 결과값 확인을 프로그래밍을 통해 자동화하는 것이 가능하다. JUnit 을 활용한 문제 해결법을 살펴본다.
참고도서 : https://roadbook.co.kr/169
[신간안내] 자바 웹 프로그래밍 Next Step
● 저자: 박재성 ● 페이지: 480 ● 판형: 사륙배변형(172*225) ● 도수: 1도 ● 정가: 30,000원 ● 발행일: 2016년 9월 19일 ● ISBN: 978-89-97924-24-0 93000 [강컴] [교보] [반디] [알라딘] [예스24] [인터파크] [샘
roadbook.co.kr
'교재 실습 > 자바 웹 프로그래밍 Next Step' 카테고리의 다른 글
2.2.1 한 번에 메서드 하나에만 집중 (0) | 2024.04.03 |
---|---|
2.2 JUnit을 활용해 main() 메서드 문제점 극복 (0) | 2024.03.27 |
2장 문자열 계산기 구현을 통한 테스트와 리팩토링 (0) | 2024.03.26 |
2. 두 번째 양파 껍질 벗기기 (1) | 2024.03.25 |
1.6 학습 방법 (1) | 2024.03.19 |
댓글