0

Catch がテストのネストされた階層を持っている方法が気に入っており、組み合わせによって機能します。xUnit フレームワークのセットアップ/ティアダウンよりも自然に感じられます。

私は今、一連のテストを持っています。私がやりたいことは、ロード/セーブシリアライゼーションテストを挿入し、そのポイントより下のすべてのテストを、最初はロード/セーブせずに、次にシリアライゼーションプロセスからロードしたデータを使用して繰り返すことです。つまり、ロード/セーブが正しかったことを証明するためです。

Catch がこれに役立つ何かを持っている場合、私は頭を悩ませることができませんか? @dependsphpUnit の場合、一連のテストについて考え@dataProvider、ブール値の入力で a を使用します。少し醜い。

(それが意味をなさない場合は、お知らせください。最小限の例を作成しようとします)

4

1 に答える 1

1

ここでの問題は、Catch がテストのツリーのような組織をたどるように設計されており、構造のすべてのリーフノードを自動的に検出し、すべてのテストが完了するまで、テストされていないコード パスを使用してテスト ケースにコールバックすることです。リーフ ノード (テスト、セクション) は独立していることを意味します。

リポジトリをテストしたいようです-データを永続化してからロードできるもの。

2 つの異なるシナリオ (シリアル化前、シリアル化後) でまったく同じテストを繰り返すには、同じテストを共通の場所に配置し、その場所を呼び出す必要があります。テスト ケースから呼び出す限り、テスト ケース以外の関数でも同じ Catch マクロを使用できます。

これを行う 1 つの可能な方法は次のとおりです。

struct TestFixture {
  Data data;
  Repository repository;
  TestFixture() : data(), instance() { }
};

void fillUpData(Data& data) {
  // ...
}

void isDataAsExpected(Data& data) {
  // Verify that 'data' is what we expect it to be, whether we
  // loaded it or filled it up manually
  SECTION("Data has ...) {
    REQUIRE(data...);
  }
}

TEST_CASE_METHOD(TestFixture, "Test with raw data") {
  fillUpData(data);
  isDataAsExpected(data);
  REQUIRE(repository.save(data));
}

TEST_CASE_METHOD(TestFixture, "Operate on serialised data") { 
  REQUIRE(repository.load(data));
  isDataAsExpected(_data);
}

考えられる代替手段の 1 つは、独自のメインを提供し、コマンドライン引数を使用して、データを最初にシリアル化するかどうかを制御することです。

Catch - Generators のまだ準備ができていない機能を使用する、私が考えることができる 3 番目の方法があります。

TEST_CASE("...") {
  using Catch::Generators;
  int iteration(GENERATE(values(0, 1)));
  const bool doSave(iteration == 0);
  const bool doLoad(iteration == 1);
  Repository repository;
  Data data;
  if (doLoad) {
    REQUIRE(repository.load(data));
  } else {
    // fill up data
  }

  REQUIRE(..data..test..);

  if (doSave) {
    REQUIRE(repository.save(data));
  }
}

この方法の利点は、フローとテストが 2 回 (2 つの値に対して) 実行されることを確認できることですが、主な欠点は、ジェネレーターが SECTION および BDD スタイルの機能と互換性がないことです。

于 2015-07-09T20:08:20.640 に答える