9

boost::serialization を使用して、1 つのレイヤーから複数のレイヤーに渡す必要があるデータ構造のファミリがあります。例えば

struct DataType1
{
    std::string field1;
    std::string field2;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & field1;
        ar & field2;
    }
};

いくつかのフィールドを見逃さないようにするために、これについて単体テストを書きたいと思います(多くの構造とフィールドがあります)。

問題は、構造体に新しいフィールドを追加し (私は間違いなくそうします)、単体テストを更新するのを忘れた場合、このフィールドは単体テストでカバーされないことです。

私の質問は、その構造 (またはクラス) が変更されたことを検出する方法です。私の考えは static_assert(sizeof(DataType1) == HARD_CODED_VALUE) を使用することでしたが、異なるコンパイラ、プラットフォーム (x64、x86)、および構成 (リリース、デバッグ) での構造サイズの違いに悩まされています。

これを処理する方法はありますか?

4

7 に答える 7

3

問題は、構造に新しいフィールドを追加し (私は間違いなくそうします)、単体テストを更新するのを忘れた場合、このフィールドは単体テストでカバーされないことです。

私の質問は、その構造 (またはクラス) が変更されたことを検出する方法です。

私のアイデアは static_assert(sizeof(DataType1) == HARD_CODED_VALUE) [...] を使用することでした

それは移植可能な解決策ではありません(あなた自身が指摘したように)。

これを処理する方法はありますか?

はい: テストの更新から始めていただけますか?

つまり、構造に何を入れるかを決定して追加し、テストを更新しないでください (忘れていない場合)。

代わりに、テストを更新して新しいシリアル化されたデータを確認し、更新されたテストが失敗することを確認してから、テストに合格するようにコードを更新します。

このアプローチ (最初に単体テストを作成/更新する) は、まさにこの問題に取り組むために (部分的に) 作成されました。

テストファーストのアプローチには、他にも利点があります。

  • YAGNIをきちんと避けます

  • 時期尚早の最適化を最小限に抑えます

  • アプリケーション/実装の機能の完全性を追跡するために自然に進化します。

于 2013-05-29T11:05:55.720 に答える
2

クラス定義にコメントを追加して、メンバーを追加するときにシリアライザーを微調整する必要があることを思い出させてください。コンピューターができることには限界があります。そのため、コード レビューは重要です。パッチは別のプログラマーにレビューしてもらい、一連の厳密なテスト ケースを用意して、最善を尽くしてください。

たとえば、特定のメソッドが構造体のすべてのメンバーを参照するようにするclangプラグインを作成できると確信していますが、本当にこれが必要ですか?それに時間を投資できますか?

とはいえ、できるだけ多くの作業をコンピューターにオフロードしようとすることにはボーナス ポイントがあります。static_assertトリックも上手です。#ifdef頻繁に構築する 1 つの特定の ABI およびアーキテクチャ用の一連の で保護すると、優れた機能を発揮する可能性があります。

于 2013-05-29T10:21:18.713 に答える
0

構造に静的変数「バージョン」を追加し、構造が変更されたときにそれを増やすことができます。

static int version = 1234;

次に、テストで次のように記述します

static_assert( DataType1::version == HARD_CODE_VALUE );

ただし、構造を変更するときにバージョンを更新するのを忘れたり、テストを更新するときに新しいメンバーを追加するのを忘れたりする可能性があります。

于 2013-05-29T10:43:05.870 に答える
0

単体テストでは、予想される struc size で static_assert チェックを実行できます。

static_assert( sizeof(DataType1)==16, "Structure changed. Update serialize method" );

プラットフォームごと (または 1 つのプラットフォームのみ) に構造体のサイズ (チェックの数字) を設定する必要があります。

于 2013-05-29T10:40:49.487 に答える