Upgrade to Pro — share decks privately, control downloads, hide ads and more …

リバーシを作って学ぶテスト駆動開発

akatsuka
May 10, 2024
110

 リバーシを作って学ぶテスト駆動開発

akatsuka

May 10, 2024
Tweet

More Decks by akatsuka

Transcript

  1. テスト駆動開発とは テストを先に書いてから実装を行う開発方法 今から何を作るかが明確になるので、開発がスムーズに進む リグレッションからの保護があるので、コード変更を比較的気軽にでき る レッド - グリーン - リファクタリング

    レッド:失敗するテストを書く グリーン:テストを通るように(愚直に)実装する リファクタリング:テストが通る状態のままでコードを整理する(重複 を排除するなど)
  2. テスト駆動開発の例 初期状態のコード抜粋 <?php namespace App\Game; class Game { private Board

    $board; // 盤面 private Color $turn; // 手番 黒か白か /** * 石を置く処理 * @param int $x x 座標 * @param int $y y 座標 */ public function process(int $x, int $y): void { // ここに処理を書く } }
  3. テスト final class GameTest extends TestCase { public function testProcess():

    void { $board = new Board(1, 8); $board->setStone(0, 0, new Stone(Color::BLACK)); $board->setStone(0, 1, new Stone(Color::WHITE)); $game = new Game($board); $game->process(0, 2); $this->assertSame($board->cell_list[0][1]?->getColor(), Color::BLACK); } }
  4. テスト結果(レッド) 1) Tests\GameTest::testProcess Failed asserting that two variables reference the

    same object. --- Expected +++ Actual @@ @@ -App\Game\Color Enum #473 (WHITE) +App\Game\Color Enum #211 (BLACK)
  5. 仮実装 置かれた場所と、ひっくり返す場所を決め打ちでとりあえず実装 public function process(int $x, int $y): void {

    $stone = new Stone($this->turn); $this->board->setStone($x, $y, $stone); if($x === 0 && $y === 2) { $this->board->cell_list[0][1]->flip(); } $this->toggleTurn(); }
  6. テスト final class GameTest extends TestCase { public function testProcess2():

    void { $board = new Board(1, 8); $board->setStone(0, 0, new Stone(Color::BLACK)); $board->setStone(0, 1, new Stone(Color::WHITE)); $board->setStone(0, 2, new Stone(Color::WHITE)); $game = new Game($board); $game->process(0, 3); $this->assertSame($board->cell_list[0][1]?->getColor(), Color::BLACK); $this->assertSame($board->cell_list[0][2]?->getColor(), Color::BLACK); } }
  7. テスト結果(レッド) 1) Tests\GameTest::testProcess2 Failed asserting that two variables reference the

    same object. --- Expected +++ Actual @@ @@ -App\Game\Color Enum #484 (WHITE) +App\Game\Color Enum #204 (BLACK) /Users/akinori/development/reversi-php2/tests/GameTest.php:66 FAILURES! Tests: 5, Assertions: 5, Failures: 1.
  8. 仮実装 置かれた場所と、ひっくり返す場所を決め打ちでとりあえず実装 public function process(int $x, int $y): void {

    $stone = new Stone($this->turn); $this->board->setStone($x, $y, $stone); if($x === 0 && $y === 2) { $this->board->cell_list[0][1]->flip(); } if($x === 0 && $y === 3) { $this->board->cell_list[0][1]->flip(); $this->board->cell_list[0][2]->flip(); } $this->toggleTurn(); }
  9. リファクタリング リファクタリングではこれまでに書いたテストが依然として通ることを確認し ながら進める while (true) { $y -= 1; if

    ($y <= 0) { break; } $cell = $this->board->cell_list[$x][$y]; if ($cell === null) { break; } if ($cell->getColor() === $this->turn) { break; } $cell->flip(); }