이번엔 2장에 나와 있는 내용 정리와 느낀점을 정리 해 보겠다.
1. main() 메소드를 활용한 테스트의 문제점.
- 소스코드 구현 후 정상적으로 동작하는지 확인 위해 일반적인 방법은 main()메소드를 활용하는 것이다.
- 실제 서비스를 담당하는 프로덕션 코드와 이 프로덕션 코드가 정상 동작 하는지 확인을 위한 main() 으로 나뉜다.
- 이 방법의 첫번째 문제점은 프로덕션코드와 main() 메서드가 함께 있다는 것이다.
- 프로덕션 코드와 테스트코드(main)을 분리할 수 있다.
- 두 번째 문제는 내가 구현하고 있는 메서드만 집중 할 수 없고, 클래스가 가지고 있는 모든 메서드를 테스트 할 수 밖에 없다.
- 다른 문제는 항상 콘솔로 확인을 할 수 밖에 없다는 것이다.
- 이를 위해 등장한 라이브러리가 JUnit 이다. 내 관심을 가지는 메서드에 대해 테스트 가능하다.
2. JUnit을 활용해 main() 메서드 문제 극복
2.1 한 번에 메서드 하나에만 집중.
- JUnit관련 라이브러리 추가 후 테스트 메서드에 @Test를 붙이면 된다.
- test 관련 코드 작성 후 Run > Run as> JunitTest를 실행해 보자.
- 각각 테스트 메서드를 독립적으로 실행할 수 있기 때문에 현재 내가 구현하고 있는 프로덕션 코드의 메서드에 집중할 수 있다.
2.2 결과 값을 눈이 아닌 프로그램을 통해 자동화
- assertEqals()를 이용하면 실행 결과를 자동화 하는 것이 가능하다.
- assertEquals(), assertTrue(), assetNull(), assertNotNull(), assertArrayEquals() 등이 있다.
- @Befoe 애노테이션을 사용해 테스트 메서드 간 영향을 미치지 않으면서 독립적으로 테스트 메서드 실행이 가능하게 한다.
- 메서드 실행마다 @Before가 실행한다.
- @After도 마찬가지로 매서드가 실행될 때마다 메서드 후 @After가 호촐된다.
3 문자열 계산기 요구사항 및 실습
3.1 요구사항
- 요구사항을 곧바로 구현을 시작하기 보다 구현 시작 전 작은 단위로 나누는 연습을 하는 것이 개발자의 역량을 키우는데 좋은 습관이다.
- 프로덕션 클래스의 메서드를 여러개 생성하는 것이 아니라, 메서드 하나에 문자열 계산기의 모둔 요구사항을 구현해야 한다.
- 여러 개의 메서드를 추가해야 하는 부분은 테스트 클래스에서 구현한다.
3.2 추가 요구사항 - 소스 코드를 완성했으면 반드시 뒤따라야 하는 과정이 중복제고, 읽기좋은 코드로 리펙토링이다. - 리펙토링은 다음 요구사항에 맞춰 진행한다. 1) 메서드가 한 가지 책임만 가지도록 구현한다. 2) 인텐트(들여쓰기) 깊이를 1단계로 유지한다. (if, while문 등등) 3) else를 사용하지 마라. - 세부 구현에 집중하도록 하지 않고 논리적인 로직을 쉽게 파악할 수 있도록 구현하는 것이 읽기 좋은 코드다. - 요구샇항이 변경되면서 메서드 이름, 변수이름을 변경하는 것 또한 중요한 리펙토링이다. - 가가 단계 개발 과정은 구현-->테스트-->리펙토링 순으로 진행한다.
책 추천 - 테스트 주도 개발 : 고품질 쾌속 개발을 위한 TDD 실천법과 도구 1장 공개자료를 실습 - 테스트 주도 개발(켄트백 저/ 인싸이트) - 리팩토링 : 코드 품질을 개선하는 객체지향 사고법(마틴 파울러) - 4장까지 반드시 읽고, 나머지는 자신이 구현한 코드를 리펙토링하면서 참조하자. 2.5 정규 표현식 - 중요한 부분을 먼저 학습 후 문자열 조작이 많아지는 시점에 학습하도록 하자. 느낀점 이전까진 Test에 대해 귀차니즘과 빠른 개발을 위해 Test코드를 작성하지 않았었다. 당연히 리펙토링도 생각해 본적이 없는 것 같다. 리펙토링도 간단한 것 부터 차근차근 연습해 보면서 몸에 익히고 Test 코드도 습관화 되도록 해야 겠다. 그럼 자세한 소스는 https://github.com/jinioh88/JavaNextStep/tree/master/Test 여기를 참조. 그럼 끝~!! 0>
1. main() 메소드를 활용한 테스트의 문제점.
- 소스코드 구현 후 정상적으로 동작하는지 확인 위해 일반적인 방법은 main()메소드를 활용하는 것이다.
- 실제 서비스를 담당하는 프로덕션 코드와 이 프로덕션 코드가 정상 동작 하는지 확인을 위한 main() 으로 나뉜다.
- 이 방법의 첫번째 문제점은 프로덕션코드와 main() 메서드가 함께 있다는 것이다.
- 프로덕션 코드와 테스트코드(main)을 분리할 수 있다.
- 두 번째 문제는 내가 구현하고 있는 메서드만 집중 할 수 없고, 클래스가 가지고 있는 모든 메서드를 테스트 할 수 밖에 없다.
- 다른 문제는 항상 콘솔로 확인을 할 수 밖에 없다는 것이다.
- 이를 위해 등장한 라이브러리가 JUnit 이다. 내 관심을 가지는 메서드에 대해 테스트 가능하다.
2. JUnit을 활용해 main() 메서드 문제 극복
2.1 한 번에 메서드 하나에만 집중.
- JUnit관련 라이브러리 추가 후 테스트 메서드에 @Test를 붙이면 된다.
- test 관련 코드 작성 후 Run > Run as> JunitTest를 실행해 보자.
- 각각 테스트 메서드를 독립적으로 실행할 수 있기 때문에 현재 내가 구현하고 있는 프로덕션 코드의 메서드에 집중할 수 있다.
import org.junit.Test; public class CalculatorTest { @Test public void add() { Calculator cal = new Calculator(); System.out.println(cal.add(1,2)); } }
2.2 결과 값을 눈이 아닌 프로그램을 통해 자동화
import org.junit.Test; import static org.junit.Assert.assertEquals; public class CalculatorTest { @Test public void add() { Calculator cal = new Calculator(); assertEquals(9,cal.add(3,6)); } }- JUnit은 assertEquals() 메서드를 제공. 첫번째 인자는 기댓값, 두번쨰 인자는 메소드 실행한 결과 값이다.
- assertEqals()를 이용하면 실행 결과를 자동화 하는 것이 가능하다.
- assertEquals(), assertTrue(), assetNull(), assertNotNull(), assertArrayEquals() 등이 있다.
- @Befoe 애노테이션을 사용해 테스트 메서드 간 영향을 미치지 않으면서 독립적으로 테스트 메서드 실행이 가능하게 한다.
- 메서드 실행마다 @Before가 실행한다.
- @After도 마찬가지로 매서드가 실행될 때마다 메서드 후 @After가 호촐된다.
3 문자열 계산기 요구사항 및 실습
3.1 요구사항
- 요구사항을 곧바로 구현을 시작하기 보다 구현 시작 전 작은 단위로 나누는 연습을 하는 것이 개발자의 역량을 키우는데 좋은 습관이다.
- 프로덕션 클래스의 메서드를 여러개 생성하는 것이 아니라, 메서드 하나에 문자열 계산기의 모둔 요구사항을 구현해야 한다.
- 여러 개의 메서드를 추가해야 하는 부분은 테스트 클래스에서 구현한다.
3.2 추가 요구사항 - 소스 코드를 완성했으면 반드시 뒤따라야 하는 과정이 중복제고, 읽기좋은 코드로 리펙토링이다. - 리펙토링은 다음 요구사항에 맞춰 진행한다. 1) 메서드가 한 가지 책임만 가지도록 구현한다. 2) 인텐트(들여쓰기) 깊이를 1단계로 유지한다. (if, while문 등등) 3) else를 사용하지 마라. - 세부 구현에 집중하도록 하지 않고 논리적인 로직을 쉽게 파악할 수 있도록 구현하는 것이 읽기 좋은 코드다. - 요구샇항이 변경되면서 메서드 이름, 변수이름을 변경하는 것 또한 중요한 리펙토링이다. - 가가 단계 개발 과정은 구현-->테스트-->리펙토링 순으로 진행한다.
import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringCalculator { int add(String text) { if(isNull(text)) { return 0; } int num = sumNumber(split(text)); return num; } public String[] split(String text) { Matcher matcher = Pattern.compile("//(.)\n(.*)").matcher(text); if(matcher.find()) { String customMark = matcher.group(1); return matcher.group(2).split(customMark); } return text.split(",|:"); } public int sumNumber(String[] values) { int sum = 0; for(String val : values) { int num = Integer.parseInt(val); isMinus(num); sum += num; } return sum; } public void isMinus(int num) { if(num<0) { throw new RuntimeException(); } } public boolean isNull(String text) { return text==null || text.isEmpty(); } }
import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; public class StringCalculatorTest { StringCalculator calculator; @Before public void init() { System.out.println("start init()..."); calculator = new StringCalculator(); } @Test public void addNull() { assertEquals(0,calculator.add("")); assertEquals(0,calculator.add(null)); } @Test public void addOne(){ assertEquals(3,calculator.add("3")); } @Test public void addShim(){ assertEquals(6,calculator.add("1,2:3")); } @Test(expected = RuntimeException.class) public void addMinus() { calculator.add("1,-2"); } @Test public void addMark() { assertEquals(5,calculator.add("//;\n2;3")); } }
책 추천 - 테스트 주도 개발 : 고품질 쾌속 개발을 위한 TDD 실천법과 도구 1장 공개자료를 실습 - 테스트 주도 개발(켄트백 저/ 인싸이트) - 리팩토링 : 코드 품질을 개선하는 객체지향 사고법(마틴 파울러) - 4장까지 반드시 읽고, 나머지는 자신이 구현한 코드를 리펙토링하면서 참조하자. 2.5 정규 표현식 - 중요한 부분을 먼저 학습 후 문자열 조작이 많아지는 시점에 학습하도록 하자. 느낀점 이전까진 Test에 대해 귀차니즘과 빠른 개발을 위해 Test코드를 작성하지 않았었다. 당연히 리펙토링도 생각해 본적이 없는 것 같다. 리펙토링도 간단한 것 부터 차근차근 연습해 보면서 몸에 익히고 Test 코드도 습관화 되도록 해야 겠다. 그럼 자세한 소스는 https://github.com/jinioh88/JavaNextStep/tree/master/Test 여기를 참조. 그럼 끝~!! 0>
댓글
댓글 쓰기