LoginSignup
1
2

More than 1 year has passed since last update.

テスト駆動開発をやってみよう

Last updated at Posted at 2022-11-28
1 / 34

これはなに?

  • ROXX社の社内勉強会にて開催した、テスト駆動開発のワークショップのためのスライドです
  • 割と筆者の主観が入りまくっています
  • 某ライオン氏のワークショップに比べれば品質は悪いと思いますので、使う場合はその辺ご了承ください

お品書き

  • そもそもテストって何?
  • テスト駆動開発とは何か
  • テスト駆動開発をやってみよう

そもそもテストって何?


ソフトウェアテスト

  • 作成したソフトウェアの正しさを、実際の動作とその出力を通して確認すること
  • 手動テストと自動テストがある
  • エンジニアの文脈では自動テストで話す場合が多い

自動テスト

  • 何らかの実装ないし仕様書をもとに、機械が実行するテスト。
  • 機械が実行するので、テスト中も人間は別の作業をすることができる
  • 機械が実行するので、同じテストを(ほぼ)同じように実行できる

なぜ自動テストをするのか

  • https://qiita.com/niisan-tokyo/items/ff793e271fd35b1a20bb
  • 常にテストを実行することで、既存の実装が破壊されていないことを確認できる
  • 既存の実装のすべてが破壊されていないかどうかを、新しい実装ごとに手動確認するのは現実的に不可能であり、自動テストを使うしかない
  • つまり、運用しつつ開発を続けるソフトウェアにおいて、自動テストは不可欠

改築したら別の個所がぶっ壊れた。
テストで防ぎたいのはこういうやつ。
kaichiku.png


自動テストは難しいのか


テストの手順

基本的にどのテストも、以下のように書かれる

public function test_something()
{
    Config::set('number', 1);// 前提条件の設定(ない場合もある)
    
    $object = new Something;
    $result = $object->run();// テスト対象を実行する

    $this->assertEquals(1, $result);// 結果の検証
}

流れが決まっているため、テストを書くときは基本的に悩まずに書くことができる


実装とテストの関係性

  • テストが通っている限り、実装を変更することができる
    • いわゆるリファクタリング
  • 実装が変わっていなければ、テストの修正・追加をすることができる
    • テストコードのメンテ(個人的にあまり必要ないとは思う)
  • 片方を固定することで、もう片方の変更を可能にする
    • 双対性というらしい

テスト駆動開発


テスト駆動開発とは?

  • テストを、仕様の確認やリグレッションのためのツールとしてだけではなく、開発の促進にも利用してしまおうという開発手法
  • TDD(Test Driven Development)などと略される
  • きれいなコードに仕上げたいという目的がある

テスト駆動開発の手順

  1. TODOリストを作成する
  2. TODOリストから一つ選んで、テストを作成し、失敗することを確認する(RED)
  3. テストが通るように最小限の実装をして、テストが通るようにする(GREEN)
  4. テストが通る状態を維持したまま、コードを整理し、きれいな状態にする(REFACTORING)
  5. 2~4を繰り返し、TODOリストがなくなったらタスクを完了とする

リファクタリング

  • 実装を、その振る舞いを変えずにコードを整理して、わかりやすく拡張性がいい感じに改善すること
  • 現時点での実装に対し、自分の考えうる最良の実装にしてやるといい
  • ここが設計の頑張りどころ。つまり、設計は後からやってくる
  • 新規の実装だけでなく、「修正」のタスクでももちろんやるべき。つまり、昔のコードに手を入れる時でも遠慮なくやる

テスト駆動開発の利点

  • タスクのゴールが明確化する
    • TODOリストを作ったのだから、それを全部こなせば、それすなわちタスクの完了である
  • 実装開始が早い
    • 経験的に、具体的な実装が存在している方が、課題にしろ困難にしろ見つけやすい。どんなに汚くても、早めにモノを用意しよう
  • わからない箇所、難しい箇所を特定できる
    • TODOリストをこなすなかで、止まった地点が難しいところである。知恵を絞り、仲間と協力して難所をくぐり抜けよう
  • リファクタリングにより最終的にきれいなコードを提供できる
    • 動くコードはいわゆるたたき台である。これを元にして良いものに仕上げよう
  • 過去のコードでも修正タスクでリファクタリングすることで、常にコードの改善を進めていける
    • 昔の恥ずかしいコードを見つけちゃっても、さっさと直そう。テストがあり、動作が保証されているのだからこそ、それが許される

テスト駆動開発とペアプロの相乗効果

  • TODOリストをお互いに確認し合える
    • 自分一人ではなく、ほかのメンバーと一緒決めるので、より信頼できるゴールだといえる
  • 難しい部分の実装が出てきた時に、相談し合える
    • ヘルプを求めたいと感じた時、すぐそこに相棒がいるのだから、相談も捗るというもの
  • リファクタリングでお互いの方針をぶつけ合い、よりいい感じの設計へと導ける
    • お互いがいいと思うモノを合わせることで、より良い実装へと昇華させよう

FizzBuzzによるテスト駆動開発の例


TODOリストを作る

PHPのテストの書き方はわかっているので、TODOリストをメソッド形式にして書き出す。

FizzBuzzTest.php
<?php
namespace Tests;

use App\FizzBuzz;
use PHPUnit\Framework\TestCase;

class FizzBuzzTest extends TestCase
{

    private FizzBuzz $obj;

    public function setUp(): void
    {
        $this->obj = new FizzBuzz;
    }

    /**
     * @test
     */
    public function 値に1をいれたら1を返す()
    {

    }

    /**
     * @test
     */
    public function 値に2を入れたら2を返す()
    {

    }

    /**
     * @test
     */
    public function 値に3をいれたらFizzを返す()
    {

    }

    /**
     * @test
     */
    public function 値に6をいれたらFizzを返す()
    {

    }

1を入れると1を返すテストを書いて失敗する

ちょっと見ずらいけど、$this->assertEquals('1', $this->obj->run(1));って書いてある
fizzbuzz1.png
何も実装していないので、動くわけがない。


動くコードにする

動くコードを作る
fizzbuzz2.png
最小限のもっとも単純なコード。
これで正しいのだ。


2を入れたら2を返してくれるか?

fizzbuzz3.png
失敗しているので、開発が必要だ


動くコードにする

自分自身を返すのが手っ取り早いので、それでやる。

fizzbuzz4.png
例題が簡単すぎるので、リファクタリングをする必要に駆られない。。。


3を入れるとFizzが返る

まあ、動きません。

fizzbuzz5.png

もちろん、これまでの実装は生きているので、一つ目と二つ目のテストは通っている


テストを通すように実装

fizzbuzz6.png


繰り返していって

TODOは全部終わった
fizzbuzz7.png
でも、きれいなコードとはいいがたい。


リファクタリング

3行ぐらいに押し込んでみる
テスト通っているから問題ない。

fizzbuzz8.png


テスト駆動開発をやってみよう


テスト駆動開発をやってみる

  • TDDを実践してみて、どういうものかを体験してみよう
  • 今回、複数の言語で、最低限テストを書ける環境を用意しているので、参加者の好きな言語での実装が可能である
  • また、今回は基本に忠実にをモットーに、以下のことを実践しよう
    • テストコードにおいて、基本的に1メソッド1アサーション
    • テストファースト
  • ピンポンプログラミングを試してみよう
    • 開発者A, Bでペアプロする時
      1. AがTODOの中でテストを作り、そのテストが失敗することを確認する
      2. Bがそのテストが成功するように最小限の実装をする
      3. A,Bで相談し、リファクタリングを実施する
      4. 1~3を繰り返す。繰り返すごとにA,Bの役割を反転させる
  • 全力でリファクタリングしよう

ピンポンプログラミング

まずTODOリストを作ろう

pinpon1.png

  • 与えられたお題のゴールを見定めよう
  • いつまでも考えられてしまうので、タイムボックスを定めるとよい

片方がまずTODOの中から一つ選んでテストを書く

pinpon2.png

  • もし書きにくそうにしていたら、もう片方がサポートしよう
  • スピードを意識してみよう

もう片方が実装する

pinpon3.png

  • 最小の実装を心掛けよう
  • こちらもスピードを意識しよう

リファクタリングをする

pinpon4.png

  • リファクタリングはペアで協力して行う
  • 相談をして、「現仕様を変えずに」「コードをきれいに」する
  • リファクタリングが必要なければ、「リファクタリングの必要なし」というけつろんをくだしてさきにすすめよ

  • 簡単そうなテストからどんどん作っていこう
  • 最小限の実装するフェーズでは、とにかく速度を優先しよう。こだわりは、リファクタリングフェーズで!
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2