Home 3장 TDD 좀 더 잘하기
Post
Cancel

3장 TDD 좀 더 잘하기

3.1 테스트 케이스 클래스의 위치

단위 테스트 케이스를 소스 구조 안에서 어디에 놓을 것인지 결정해야 한다.

1)테스트 대상 소스와 테스트 클래스를 같은 곳에

테스트 클래스와 같은 패키지 내에 놓는 가장 기본적인 형태이다. 간단한 테스트 생성시 외에 사용하지 않는다.

2)테스트 클래스는 하위 패키지로

예) src/bank - 제품코드 클래스, src/bank/test - 테스트 케이스 클래스

3)최상위 패키지를 분리

제품 클래스는 main 패키지에, test 클래스는 test 패키지에 따로 분리

흔히 많이 사용하는 방식으로 최상위 패키지부터 업무 코드와 테스트 코드를 분리해서 작성할 수 있다. 단점으로는 default, protected로 선언된 메소드들에 대해서는 테스트 코드를 작성할 수 없다.

4)소스 폴더는 다르게, 패키지는 동일, 컴파일된 클래스는 각각 다른 곳으로

장점으로 대상 클래스와 테스트 클래스를 동일한 패키지로 선언할 수 있고, 접근 범위 default, protected로 선언된 메소드도 테스트 케이스로 작성할 수 있다. 또 대상 클래스와 테스트 클래스의 위치가 최상위 폴더부터 다르게 만들어지기 때문에 서로 섞일 염려가 없다. 따라서 가장 권장하는 스타일이다.

5)테스트를 프로젝트로 분리

동일 프로젝트 내에 제품 코드 클래스와 테스트 클래스가 함께 존재하면 각자 사용하는 라이브러리를 클래스패스로 공유하게 된다. 따라서 외부 라이브러리 의존 관계를 좀 더 확실하게 구분하고자 할 때는 프로젝트 단위로 분리해 놓기도 한다.

이클립스 기준) Test 프로젝트를 생성하고 Java Build Path 항목의 Project > Add > 참조할 클래스 추가, 이렇게 하면 JUnit 라이브러리조차 필요 없어진다.

6)메이븐 스타일

  • /src/main/java : 제품 코드가 들어가는 위치
  • /src/main/resource : 제품 코드에서 사용하는 각종 파일, XML 등의 리소스 파일
  • /src/test/java : 테스트 코드가 들어가는 위치
  • /src/test/resource : 테스트 코드에서 사용하는 각종 파일, XML 등의 리소스 파일

3.2 테스트 메소드 작성 방식

1)테스트 대상 메소드와 이름을 1:1로 일치

1
2
3
4
5
6
//테스트 대상
public int getBalance() {....}

//테스트 코드
@Test
public void testGetBalance(){...}

테스트 메소드의 숫자가 적어져서 보기 편하고, 1:1로 연관지어 생각할 수 있다는 장점이 있다. 하지만 성공 케이스와 실패 케이스가 중간 중간 섞여 있을 수 있는데 구별이 불가능하다는 단점이 있다.

2)테스트 대상 메소드의 이름 뒤에 추가적인 정보를 기재

1
2
3
4
5
6
7
8
9
//테스트 대상
public void withdraw(int money) {...}

//테스트 코드
@Test
public void testWithdraw_마이너스통장인출() {...}

@Test
public void testWithdraw_잔고가0원일때() {...}

테스트 대상 코드의 메소드 단위로 작성하게 되고, 케이스 별로 테스트 메소드를 추가하는 방식으로 가장 권장되는 방식이다.

3)테스트 시나리오에 집중

테스트 시나리오에 집중해서 대상 클래스 자체의 통합적인 기능을 테스트할 때 사용한다. 통합 테스트, 사용자 테스트의 특성상 일반적으로 ‘선조건->수행->예상결과’ 식의 테스트 시나리오를 갖는다.

1
2
3
4
5
6
7
8
public class 환승테스트 {
  @Test
  public void 평일_30분이내에_환승_성공한다() {...}

  @Test
  public void 평일_30분이후에_환승_실패한다() {...}

}

3.3 테스트 케이스 작성 접근 방식

테스트 클래스의 구성뿐만 아니라 테스트를 작성하는 데 있어서 어떤 형태로 접근할 것인가에 대한 논의가 필요하다.

  • 설계자와 개발자가 분리되어 있는 경우 : 설계자가 설계문서에 테스트 케이스(테스트 시나리오)를 작성해놓아야 한다.
  • 개발자가 설계와 개발을 함께 하는 경우 : 개발자가 고객과 합의가 가능할 정도로 능동적으로 참여할 수 있는 상황이라면 테스트 작성 범위에 대해 크게 고민할 필요가 없다.
  • 무엇을 테스트 케이스로 작성할 것인가? : 시나리오식 접근 방법에는 정상적인 흐름일 때 동작해야 하는 결과값을 선정해놓는 방식인 해피데이 시나리오, 예외나 에러 상황에 대한 결과값을 적은 블루데이 시나리오 등이 있다.

3.4 TDD의 한계

  • 동시성 문제 : 동시성이 걸려있는 코드에 대한 테스트 케이스 작성은 테스트 자체를 무결하게 유지하기가 어렵다.
  • 접근제한자 : private으로 되어있는 메소드는 일반적인 방법으로는 테스트가 불가능하다. (public으로 되어있는 메소드만 테스트해도 무방하다는 경향이 대세)
  • GUI : 웹 애플리케이션에 해당하는 영역이 TDD를 적용하기 곤란한 GUI 영역이다. 최선의 전략은 ‘UI 영역에는 비즈니스 로직이 최대한 들어가지 않게 작성한다’ 이다.
  • 의존성 모듈 테스트
This post is licensed under CC BY 4.0 by the author.

2장 JUnit과 Hamcrest

4장 한계 돌파를 위한 노력, Mock을 이용한 TDD