はむはむエンジニアぶろぐ

このブログのコンセプトは"ハッキングの為なら愛する家族を傷つけることをいとわない" 自分にとってエンジニアリングは "手段ではなく生きる目的" である

PHPUnit 壊れているテストを徐々に改良していく

f:id:secret_hamuhamu:20150404170600p:plain
PHPUnitで、テストを回した際、コケまくるなんて経験ありませんか?
...FFFFFFみたいに。
実装のリファクタリングを行ったとか、テストがコケたまま放置されていたとか色々あると思います。

TDD的にこれらのテストの修正を一気に行うことは、アンチパターンとされています。
壊れているテストを徐々に改良していきたいと思います。

環境構成

  • PHP 5.4.40
  • PHPUnit 4.3.4


壊れているテストを徐々に改良するには?

テストがコケまくっている場合、どうしてますか?
actualとexpectedの差が、ズラッと流れて見難いですよね。
例えばこんなやつ。

1) TestSelectionTest::テスト1_group2
Failed asserting that Array &0 (
    0 => 1
    1 => 1
    2 => 1
    3 => 1
    4 => 1
    5 => 1
    6 => 1
) is identical to Array &0 (
    0 => 0
    1 => 0
    2 => 0
    3 => 0
    4 => 0
    5 => 0
    6 => 0
).

/Users/y-ohhashi/programs/PHP/TestSelectionTest.php:29

2) TestSelectionTest::テスト2_group2
Failed asserting that Array &0 (
    0 => 1
    1 => 1
    2 => 1
    3 => 1
    4 => 1
    5 => 1
    6 => 1
) is identical to Array &0 (
    0 => 0
    1 => 0
    2 => 0
    3 => 0
    4 => 0
    5 => 0
    6 => 0
).

/Users/y-ohhashi/programs/PHP/TestSelectionTest.php:38

3) TestSelectionTest::テスト3_group2
Failed asserting that Array &0 (
    0 => 1
    1 => 1
    2 => 1
    3 => 1
    4 => 1
    5 => 1
    6 => 1
) is identical to Array &0 (
    0 => 0
    1 => 0
    2 => 0
    3 => 0
    4 => 0
    5 => 0
    6 => 0
).


こういう時どうしてますか?
目grepで頑張る?コケているテストをコメントアウトする?
目grep余裕な人なら、そのままで大丈夫ですw。辛いと感じているならやり方を変えたほうがいいです。
もし、コメントアウトしているならば、よろしくない習慣です。
何故なら、コメントアウトの取り外しを忘れてしまう恐れがあるからです。

コメントアウトしたままコミットされてしまうと、そのテストの存在意義がなくなります。
共同開発されているなら混乱を招くことになるでしょう。

では、どうするか?

markTestIncomplete を使ってテストに未完成の印をつけてあげます。


テストに未完成の印をつける

このように失敗するテストに markTestIncomplete をつけてあげます。

<?php

class TestSelectionTest extends PHPUnit_Framework_TestCase
{
    /** @test */
    public function テスト1()
    {
        $this->assertTrue(true);
    }

    /** @test */
    public function テスト2()
    {
        $this->assertTrue(true);
    }

    /** @test */
    public function テスト3()
    {
        $this->markTestIncomplete(
            'このテストは、まだ実装されていません。'
        );
        $this->assertSame([0,0,0,0,0,0,0,], [1,1,1,1,1,1,1]);
    }

    /** @test */
    public function テスト4()
    {
        $this->markTestIncomplete(
            'このテストは、まだ実装されていません。'
        );
        $this->assertSame([0,0,0,0,0,0,0,], [1,1,1,1,1,1,1]);
    }

    /** @test */
    public function テスト5()
    {
        $this->markTestIncomplete(
            'このテストは、まだ実装されていません。'
        );
        $this->assertSame([0,0,0,0,0,0,0,], [1,1,1,1,1,1,1]);
    }
}


この状態で、テストを実行するとこうなる。
f:id:secret_hamuhamu:20150719034402p:plain

greenred の間である黄色いの出力と未完成であることを表す I が表記される。

コケているテストに対して、 markTestIncomplete することで、見難かったactualとexpectedの差が、スッキリする。
これで、コケているテストを徐々に改良はずである。

面倒くさいかもしれないけど、未完成のテストの数も把握できるのでテストをコメントアウトして回すよりは良いと思います。

最近読んだ本

知識ゼロから学ぶソフトウェアテスト 【改訂版】

知識ゼロから学ぶソフトウェアテスト 【改訂版】

テスト駆動開発入門

テスト駆動開発入門

  • 作者: ケントベック,Kent Beck,長瀬嘉秀,テクノロジックアート
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2003/09
  • メディア: 単行本
  • 購入: 45人 クリック: 1,058回
  • この商品を含むブログ (161件) を見る

テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計

テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計

レガシーコード改善ガイド (Object Oriented SELECTION)

レガシーコード改善ガイド (Object Oriented SELECTION)

  • 作者: マイケル・C・フェザーズ,ウルシステムズ株式会社,平澤章,越智典子,稲葉信之,田村友彦,小堀真義
  • 出版社/メーカー: 翔泳社
  • 発売日: 2009/07/14
  • メディア: 大型本
  • 購入: 45人 クリック: 673回
  • この商品を含むブログ (152件) を見る