Heo Jun
91
2019-06-11 20:28:10 작성 2019-06-11 20:38:14 수정됨
0
934

TDD 볼링게임 만들기


안녕하세요. 

최근 흥미로운 TDD 연습 프로젝트를 발견하여, 공유하려고 글을 씁니다.

소개해드릴 프로젝트는 Bowling Game Kata 로 아마 저빼곤 이미 다 알고계실지도 모를 프로젝트입니다;;

이 글은 정보 공유와 개인의 학습을 목적으로 하기때문에 정확하지 못한 내용이 있을 수 있습니다. 많은 피드백 부탁드립니다.



Bowling Game Kata

  • 엉클밥이라는 애칭으로 유명한  Clean Code의 저자 로버트 C 마틴이 학습용 프로젝트로 제안한 볼링 점수 계산 프로그램 입니다.



프로젝트를 진행하기에 앞서 볼링 점수를 계산하는 방법을 간단하게 설명드리겠습니다.

볼링 점수 계산

  1. 총 10프레임 진행하며, 한 프레임에 2회 공을 굴릴 수 있는 기회가 주어진다.
  2. 핀 1개는 1점이다.
  3. 스페어는 기본 10점 + 다음 프레임 1구
  4. 스트라이크는 기본 10점 + 다음 프레임 1구 +  2구
  5. 10 프레임에 스트라이크나 스페어가 나오면 최대 3번 공을 굴릴 수 있다.



요구사항

  • roll 은 플레이어가 공을 굴릴때마다 호출된다. 파라미터인 pins는 공을 굴렸을 때 쓰러트린 핀의 갯수를 나타낸다.
  • score 는 게임이 끝났을때만 호출되며, 게임의 총 점수를 계산한다.



TDD Cycle

 

Red-Green-Refactor
1. Red : 테스트 코드를 작성한다.
2. Green : 테스트 코드를 통과할 수 있는 최소한의 기능 코드를 작성한다.
3. Refactor : 작성한 코드를 리팩토링한다.

본 글은 레드-그린-리팩터라고 불리는 TDD Cycle을 사용해서 진행해보려 합니다.


서론이 길었습니다. 
본격적으로 TDD-BowlingGame 진행해보도록 하겠습니다.

  1. BowlingGame이라는 이름으로 Java 프로젝트를 생성합니다.

  2. test라는 이름으로 Source Folder를 생성해줍니다.

  3. BowlingGameTest 라는 이름으로 JUnit Test Case파일을 생성해줍니다.


프로젝트 생성과 테스트자바 파일까지 만드셨다면 또 본격적으로(?) BowlingGame을 만들어보도록 하겠습니다.
  
First Step
  1. Red 
    1. 가장 먼저 Game 클래스가 생성이 되는지를 확인하기위한 테스트를 작성해봅시다. 
public class BowlingGameTest {
       @Test
       public void canCreateGame() {
              Game game = new Game();
       }
}
  1. Green
    1. 테스트 통과!
public class Game {
}
  1. Refactor
    1. 리팩토링할 코드가 없네요. 다음으로!

  1. Red 
    1. 그럼 다음으로 roll 이라는 함수를 만들 수 있는지 확인해봅니다.
public class BowlingGameTest {
       @Test
       public void canCreateGame() {
              Game game = new Game();
       }
       @Test
       public void canRoll() {
              Game game = new Game();
              game.roll(0);
       }
}
  1. Green
    1. 최소한의 코드로 테스트를 통과시킵니다! 요구사항에 맞춰서 매개변수의 이름을 pins로 바꿔줍니다.
public class Game {
       public void roll(int pins) {      
       }
}
  1. Refactor
    1. 테스트를 통과시켰으니 리팩토링할 코드가 있는지 살펴봐야겠지요. 테스트코드를 보면 Game game = new Game();이 중복되어서 사용되는 것을 볼 수 있습니다!
    2. 아래처럼 바꿔주고 여전히 테스트를 통과하는지 확인해 줍니다.
public class BowlingGameTest {
       private Game game;
       
       @Before
       public void setUp() {
              game = new Game();
       }
       @Test
       public void canRoll() {    
              game.roll(0);
       }
}
  1. Red 
    1. 그럼 이제 score 함수를 만들 수 있는지 확인해봐야합니다.
    2. 그런데 요구사항에 score 함수는 게임이 끝났을때만 호출할 수 있다고 되어있습니다.
    3. 여기서 게임을 가장 쉽게 끝낼 수 있는 방법이 무엇일까요?
    4. 바로 GutterGame입니다. (거터게임은 모두 0점을 기록한 게임을 말합니다.)
public class BowlingGameTest {
       @Before
       public void setUp() {
              game = new Game();
       }
       @Test
       public void canRoll() {    
              game.roll(0);
       }
       @Test
       public void gutterGame() {
              for (int i = 0; i < 20; i++) {
                     game.roll(0);
              }
              assertEquals(0, game.score());           
       }
}
  1. Green
    1. 자, 이제 Gutter 게임 테스트를 통과시켜야합니다.
    2. 이때 score()의 return 값을 -1로 우선 테스트해봅니다. 이 과정은 내가 작성한 테스트의 신뢰성을 확인해보기 위한 작업입니다.
public class Game {
       public void roll(int pins) {      
       }
       public int score() {
              return 0;
       }
}
  1. Refactor

    1. 리팩토링할 코드가 없네요. 


여기서 볼링게임 1편을 마치겠습니다.

볼링게임은 총 5 step으로 구성되어있습니다.


어떤 종류의 피드백도 환영입니다.

다시한번 많은 피드백 부탁드립니다.




2
5
  • 댓글 0

  • 로그인을 하시면 댓글을 등록할 수 있습니다.