Given When Then(GWT)とArrange Act Assert(AAA)の違いは?


13

TDDには、アレンジアサート(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. SpecFlowやCucumberなど、さまざまなBDDフレームワークのキーワードがWhenおよびThenである場合

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


3
「自然言語のように読む」ことを除いて、違いは見られません。取り決めが与えられた場合、アクションが発生すると、新しい状態に関することを主張します。
シェードジョブポストマス

いくつかの関連するポイントを見つけたと思いますが、追加の違いがある回答を受け取ることはまずありません。このフォーマットは完全に方法論に依存しませんが、小規模で独立したテストを推奨するため、その価値のある単体テストにはAAAのみを使用します。
アモン

回答:


9

あなたはあなたの質問に違いを非常によくリストしたと思いますが、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
}

コンピューター(つまりプログラマー)がビジネスに付加価値を与えているかどうかを人々が疑問に思うとき、私はいつもそれが面白いと感じます。それは可能性が本当にちょうど大きな利己bamboozleこと?ビジネスマネージャーは、プログラミングの目的をどのように達成しているかを理解するために、プログラミングについて十分に学習するか、単にそれが心配ではないことを信頼する必要があると思います。心房細胞の遅延整流電流の開始に影響を与える化学物質がどのように機能するのか、私は本当に理解できないかもしれませんが、心臓不整脈を起こさないことがどれほど良いかを確実に感じることができます。

抽象化は、コンピューターサイエンスだけでなく重要です。人々はさまざまな分野の専門知識を持ち、その専門知識を他の人と伝えることができることはビジネスにとって重要です。GWTは、プログラマーと(プログラム|プロジェクト)マネージャーが通信するのに役立つ抽象化です。第二に、プログラマーとして、プログラマーがビジネスにとって価値をほとんどまたはまったく生み出さない可能性があることは容易に想像できます。最後に、GWTは、プログラマーとマネージャーにコミュニケーションをとらせる方法であるだけでなく、ビジネスで試してみたい多くのツールの1つであることに注意してください。
フランクブライス

また、心臓の不整脈補正メカニズムが機能する理由だけでなく、それを挿入する前に機能する理由を医師に理解してもらいたいと思います。GWTテストは、「なぜ」に答えるのに役立つはずです。プログラマとプロダクトマネージャー間の通信を支援するGWTは、化学者と医師間の通信に類似しています。プロダクトマネージャーはユーザーにどのような機能を提供するかを伝え、医師は心臓不整脈の補正によって得られる価値を患者に伝えます。
フランクブライス

ええ、専門医がこの薬を推薦し、病院で私と一緒に開始されるのを監視しました。私の年配の心臓病専門医は、それが機能することを知っていたので、かかりつけの医師はこの薬を聞いたことがありませんでした。保険会社に、なぜ93,000ドルの病院旅行が医学的に必要なのか(別の事件)を説明するのはさらに楽しいことです。それで、私はそれをすべて説明する1ページの手紙を書くことができたのは、2年の賃金の価値がありました。専門知識は命を救います。そしてお金。

4

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


2

まったく違いはありません。
テストの3つの状態:指定
=配置、
タイミング=行為、
それから=アサート。

質問で提供した違いは、GWDとAAAではなく、TDDとBDDの違いです。

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);
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.