0

ユニットテストでしばらく遊んでいるという事実にもかかわらず、単一の機能である「ユニット」の概念を実際には理解できません。

たとえば、次の形式で魔法のメソッドのグループをテストしていますnewXxx

public function testMagicCreatorWithoutArgument()
{
    $retobj = $this->hobj->newFoo();

    // Test that magic method sets the attribute
    $this->assertObjectHasAttribute('foo', $this->hobj);
    $this->assertInstanceOf(get_class($this->hobj), $this->hobj->foo);

    // Test returned $retobj type
    $this->assertInstanceOf(get_class($this->hobj), $retobj);
    $this->assertNotSame($this->hobj, $retobj);

    // Test parent property in $retobj
    $this->assertSame($this->hobj, $retobj->getParent());
}

ご覧のとおり、このテスト メソッドにはアサーションの 3 つの「グループ」があります。「単体テスト」の原則に従うために、それらを3つの単一のテスト方法に分割する必要がありますか?

分割は次のようになります。

public function testMagicCreatorWithoutArgumentSetsTheProperty()
{
    $this->hobj->newFoo();

    $this->assertObjectHasAttribute('foo', $this->hobj);
    $this->assertInstanceOf(get_class($this->hobj), $this->hobj->foo);
}

/**
 * @depends testMagicCreatorWithoutArgumentReturnsNewInstance
 */
public function testMagicCreatorWithArgumentSetsParentProperty()
{
    $retobj = $this->hobj->newFoo();

    $this->assertSame($this->hobj, $retobj->getParent());
}

public function testMagicCreatorWithoutArgumentReturnsNewInstance()
{
    $retobj = $this->hobj->newFoo();

    $this->assertInstanceOf(get_class($this->hobj), $retobj);
    $this->assertNotSame($this->hobj, $retobj);
}
4

1 に答える 1

4

あなたのテスト方法はこれをテストしています:

   $retobj = $this->hobj->newFoo();

1 つのテストで、この 1 つのオブジェクトに対して複数のアサーションを実行します。それは不合理ではないようです。

1 つのテストで複数のメソッド呼び出しをテストしている場合は、さらに懸念されます。なんで ?初期のアサーションはテストを中止し、それ以降のメソッドでテストを実行しません。これは、せいぜい2 番目の方法がテストされなかったことを意味し、最悪の場合、2 番目のテストで明らかになった証拠が隠されます (その証拠は、最初の失敗の原因または範囲を特定するのに役立つ可能性があります)。

このため、単体テスト メソッドであまりにも多くのアサーションを避けるようにしています。null オブジェクトをチェックしてから (同じテストで) 値が設定されたフィールドをチェックすることは不合理ではありません。ただし、これらのアサーションを連鎖させることはせず、返された同じエンティティのさまざまな機能をテストする複数のテストを行います。

いつものように、ここにはある程度の実用性があります。

于 2012-12-17T13:33:43.210 に答える