3

BDD と MSpec の初心者である私は、BDD 全般、特に MSpec に関連するベスト プラクティスと良い習慣について、まだ確信が持てません。

次の例を改善できますか? ベストプラクティスと良い習慣に従っていますか?

  1. 仕様クラスと動作の命名は問題ありませんか?
  2. このシナリオで動作を使用する必要がありますか、それとも仕様クラスに共通の基本クラスを使用する必要がありますか?
  3. ここがなくても大丈夫Establishですか?
  4. テスト データを取得するためにスタティック ファクトリ メソッド (TestDataメソッド) を使用する必要がありますか?それとも仕様自体でデータを作成する必要がありますか?
  5. 使用できる動作の各プロパティをテストする代わりに、result.Equals()2 つのことをテストすることになりますが、これは良くありません。

この例を、より良いと思われるものに自由にリファクタリングしてください。

[Subject(typeof(DataItemReader))]
public class When_reading_a_DataItem_from_stream
{
    Because of = () =>
    {
        using (var reader = new DataItemReader(
            new MemoryStream(TestData.GetNormalDataItemAsByteArray()), Encryption.None))
        {
            result = reader.ReadItem();
        }
    };

    Behaves_like<DataItemReader_that_reads_correctly> behavior;

    protected static DataItem result;
}

[Subject(typeof(DataItemReader))]
public class When_reading_a_DataItem_from_encrypted_stream
{
    Because of = () =>
    {
        using (var reader = new DataItemReader(
            new MemoryStream(TestData.GetNormalDataItemAsByteArrayEncyrpted()), Encryption.Default))
        {
            result = reader.ReadItem();
        }
    };

    Behaves_like<DataItemReader_that_reads_correctly> behavior;

    protected static DataItem result;
}

[Behaviors]
public class DataItemReader_that_reads_correctly
{
    protected static DataItem result;

    It should_read_the_correct_DataItem = () =>
    {
        var testItem = TestData.GetNormalDataItem();
        result.Property1.ShouldEqual(testItem.Property1);
        result.Property2.ShouldEqual(testItem.Property2);
        result.Property3.ShouldEqual(testItem.Property3);
    };
}
4

1 に答える 1

6

おそらく、世界が仕様について考えていることよりも、あなたとあなたのチーム/同僚/「あなたの後にこのコードを読まなければならない人」がそれらから得ることができるものの方が多いでしょう.

ある開発者の観点から:

  1. 大文字と小文字の区別と命名は、コードで読み取り可能なものに従います。HTML 抽出の良い点は、最終的に読みやすい仕様を取得できることです。私が読んだものの多くは、すべて小文字などに焦点を当てています。ただし、私はあなたのように私の言葉を言います:適切で読みやすいケーシング。

  2. このような 1 対 1 の場合、ビヘイビアーは読みやすさに優れています。私は基本クラスを使用して、コンテキストを確立し、反復的で一般的なアサーションの期待と動作を設定します。

  3. Establish常に「テスト前に環境をセットアップする」ことを意味してきました。あなたが持っている2つの例では、おそらく次のように書き直します。

    Establish context = () => var reader = 
           new DataItemReader(new MemoryStream(     
           TestData.GetNormalDataItemAsByteArray()),                               
           Encryption.None));
    
    Because of = () => result = reader.ReadItem();
    
    Cleanup after = () => reader.Dispose();
    

    仕様は「読み取る」DataItemに焦点を当てているため、アクションまたはそれBecauseだけです。繰り返しますが、好みの問題です。

  4. スタブを手動で作成するか、スタブ/モッキング エンジン (FakeItEasy http://code.google.com/p/fakeiteasy/など) を使用する再利用可能な静的ファクトリを使用します。私の考えでは、スタブの内容/作成は実際のテストにはほとんど関係がなく、スタブによってブラックボックスとして扱われるべきです (それがテストを書いている理由ですよね?)。

  5. 私は各プロパティに個別に (あなたが持っているように) 焦点を当てて、それらが私の期待に確実に応えられるようにします。Equals をオーバーライドすると、仕様の一部ではない、または無関係なプロパティの等価性をチェックする可能性があります。

管理の「ベスト プラクティス」があるかどうかはわかりません (github サイトにいくつかのヒントがあります: https://github.com/machine/machine.specifications#readme )。MSpec を使用している他のプロジェクトを見て、彼らが仕様をどのように扱っているかを観察することで、私のコーディング スタイルのいくつかが変わったことに気づきました。

于 2011-08-09T17:13:43.410 に答える