web-dev-qa-db-ja.com

与えられたとき(GWT)とアレンジアサート(AAA)の違いは?

TDDには、Arrange Act Assert(AAA)構文があります。

[Test]
public void Test_ReturnItemForRefund_ReturnsStockOfBlackSweatersAsTwo_WhenOneInStockAndOneIsReturned()
{
    //Arrange
    ShopStock shopStock = new ShopStock();
    Item blackSweater = new Item("ID: 25");
    shopStock.AddStock(blackSweater);
    int expectedResult = 2;
    Item blackSweaterToReturn = new Item("ID: 25");

    //Act
    shopStock.ReturnItemForRefund(blackSweaterToReturn);
    int actualResult = shopStock.GetStock("ID: 25");

    //Assert
    Assert.AreEqual(expectedResult, actualResult);
}

BDDの記述では、テストは同様の構造を使用しますが、Given When Then(GWT)構文を使用します。

    [Given(@"a customer previously bought a black sweater from me")]
    public void GivenACustomerPreviouslyBoughtABlackSweaterFromMe()
    { /* Code goes here */   }

    [Given(@"I currently have three black sweaters left in stock")]
    public void GivenICurrentlyHaveThreeBlackSweatersLeftInStock()
    { /* Code goes here */   }

    [When(@"he returns the sweater for a refund")]
    public void WhenHeReturnsTheSweaterForARefund()
    { /* Code goes here */   }

    [Then(@"I should have four black sweaters in stock")]
    public void ThenIShouldHaveFourBlackSweatersInStock()
    { /* Code goes here */   }

それらはしばしば同じと考えられていますが、違いがあります。主なものは次のとおりです。

  1. GWTは、BDDフレームワークの機能ファイルの仕様に直接マップできます。

  2. GWTは、プレーンな英語の使用を奨励し、各部分が何をしているかの簡単な説明をすることにより、開発者でない人にとっても理解しやすくなります

  3. WhenとThenは、SpecFlowやCucumberなどのさまざまなBDDフレームワークのキーワードです

私の質問は、AAAとGWTの間に(名前以外に)他の違いがあるのですか?そして、上記で指定されたもの以外に、一方が他方よりも優先される理由はありますか?

13
Cognitive_chaos

あなたの質問には違いがよく記載されていたと思いますが、2つのアプローチの見方に関する私の意見をいくつか追加します。

AAAは、自分のコードをテストするときに非常に役立ちます。私が自分でプロジェクトやライブラリに取り組んでいる場合は、AAAを使用します。テストを実行するために必要なものをセットアップして、テストするだけです。セットアップが簡単で、コードが期待どおりに機能していることをすばやく確認できます。

GWTは、プログラマーが行う作業をビジネス価値にマッピングする必要があるビジネス環境で役立ちます。ビジネス上の価値は機能によってマッピングされますが、機能がバグを引き起こさないことが期待されます。機能をプログラミングタスクにマッピングするには多くの戦略がありますが、その1つは要件によるものです。私の経験では、要件はユーザーレベルの要件からユーザーが実行する小さなタスクに至るまでさまざまです。 プログラマーが行っている作業が顧客/ユーザーにどのように影響しているか、したがってプログラマーがビジネスに価値を付加している理由をマネージャーが理解するのは簡単です

  • ユーザーレベルの要件:倉庫の在庫が少なくともN個ある場合、ユーザーがN個のアイテムを購入すると、倉庫はN個のアイテムをユーザーに発送します。
  • システムレベルの要件1:在庫システムの在庫にN個のアイテムがある場合、N個のアイテムのリクエストが在庫システムに入力されると、そのタイプのアイテムの在庫数が減少します。
  • システムレベルの要件2:支払いシステムの在庫がNアイテムの場合、Nアイテムのリクエストが支払いシステムに入力されると、支払いシステムはユーザーにNアイテムの料金を請求します。
  • ...
  • プログラマーレベルの要件1:5枚のセーターが在庫にあり、3枚のセーターが在庫から削除されると、2人のセーターが在庫に残ります。
  • ...

この種の要件構造により、すべてのプログラマレベルの要件がツリーをユーザーレベルの要件にマップするツリー状の設計が可能になります。このようにして、プログラマーレベルの要件が失敗した場合、影響を受けるユーザーレベルの要件がわかります。

対照的に、AAAテストは次のようになります。これはプログラマにとって非常に面倒で、ビジネスには役立ちません。これは、同様の要件のツリー構造をAAAテスト戦略から作成できないと言っているわけではありませんが、AAAの言語では何も簡単に行うことができません。

public void Test_CaseWhereThereAreEnoughSweatersLeft() {
    // Arrange
    // setup Sweater Inventory mock (DB mocks, etc)
    // count = 5
    // when The number of sweaters remaining is request, return count
    // when Inventory is requested to remove N items, then count = count - N

    // Act
    // call the Unit Under Test to remove 3 items from inventory

    // Assert
    // the number of sweaters in the inventory is 2
    // the removal should return indicating a successful removal of items from the inventory
}

public void Test_CaseWhereThereAreNotEnoughSweatersLeft() {
    // Arrange
    // setup Sweater Inventory mock (DB mocks, etc)
    // count = 2
    // when The number of sweaters remaining is request, return count
    // when Inventory is requested to remove N items, then count = count - N

    // Act
    // call the Unit Under Test to remove 3 items from inventory

    // Assert
    // the number of sweaters remaining is still 2
    // the removal should return an error indicating not enough items in the inventory
}
9
Frank Bryce

使用しているフレームワークに依存していると思います。一般に、私の理解では、AAAはNUnitフレームワークでサポートされているため、その点で自然な選択です。 TDDとBDDの理論的な違いについては、それらはわずかに見えます。 this リンクを参照してください。説明するのに私よりも資格のある人がいます。

4
George Grainger

全く違いはありません。
3つのテスト状態:
指定=アレンジ、
=行動する場合
その後=アサート。

質問で提供した違いは、TDDとBDDの違いであり、GWTとAAAではありません。

TDDでは、1つのテストに対して3つの異なる方法を使用できます

public class TestsOfFormatMethod
{        
    public void Arrange() { // set dependencies }
    public string Act() { // return formattted result }
    public string AssertThatFormatIsEmpty()
    {
        Arrange();
        var actual = Act();
        Assert.IsEmpty(actual);
    }
}
2
Fabio