質問

ユニットテストの目的で、ネットワーク応答をモックアップする必要があります。応答は通常、const vector<uint8_t>として格納されているバイトストリームです。しかしながら、単体テストのために、CPPファイルにハードコードされているか、同じ解ソリューション内のファイルから読み取るデータをベクトルを作成したいと思います。マイ例データは約6 KBです。 Googletest

役に立ちましたか?

解決

おそらく(a)あなたはいくつかの役割のために大きな一連のデータを必要とする テストケースはそれを読むだけです。これは(クラス)グローバルデータであるかもしれません。 constアクセス

おそらく(b)あなたはいくつかの役割のために大きな一連のデータを必要とします テストケースはそれを読み書きまたは破壊します。これは必要です テストケースごとにRENITIALIZALIZENATION、非一般的なカデトラックアクセスがあります。

おそらく両方。どちらの場合も、従来のGoogletSestの実装であろう a テストフィクスチャ データの取得をカプセル化するために、 フィクスチャの仮想constメンバー関数の実装、および 固定具のゲッター方式でアクセスしてください。

次のプログラムは、どちらも1つの場合を提供するフィクスチャを示しています ファイルから取得された可変データとグローバル定数データ。

#include <vector>
#include <fstream>
#include <stdexcept>
#include "gtest/gtest.h"

class foo_test : public ::testing::Test
{
protected:
    virtual void SetUp() {
        std::ifstream in("path/to/case_data");
        if (!in) {
            throw std::runtime_error("Could not open \"path/to/case_data\" for input");
        }
        _case_data.assign(
            std::istream_iterator<char>(in),std::istream_iterator<char>());
        if (_global_data.empty()) {
            std::ifstream in("path/to/global_data");
            if (!in) {
                throw std::runtime_error(
                    "Could not open \"path/to/global_data\" for input");
            }
            _global_data.assign(
                std::istream_iterator<char>(in),std::istream_iterator<char>());
        }
    }
    // virtual void TearDown() {}   
    std::vector<char> & case_data() {
        return _case_data;
    }
    static std::vector<char> const & global_data() {
        return _global_data;
    }

private:
    std::vector<char> _case_data;
    static std::vector<char> _global_data;

};

std::vector<char> foo_test::_global_data;

TEST_F(foo_test, CaseDataWipe) {
  EXPECT_GT(case_data().size(),0);
  case_data().resize(0);
  EXPECT_EQ(case_data().size(),0);
}

TEST_F(foo_test, CaseDataTrunc) {
  EXPECT_GT(case_data().size(),0);
  case_data().resize(1);
  EXPECT_EQ(case_data().size(),1);
}

TEST_F(foo_test, HaveGlobalData) {
  EXPECT_GT(global_data().size(),0);
}


int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
.

ケース(a)では、グローバルセットアップ Setup()をサブクラシにすることによるメンバー関数ですが、わかりません そのようにすることを好むための一般的な理由。

...またはそれをハードコードする?

テストデータをすべてのファイルに保持するか、またはハードコードを保持するかどうかの問題に テストソースで。 この時点で幸せな読者は今から退屈されます

一般的な問題としては、状況に瀕している問題の問題があり、考えていない Googletestの使用はスケールをマテリアルにヒントします。主な考慮事項と思います IS:は、テストデータの項目を変えることができることが望ましいです。 テストスイートの再構築?

テストスイートを再構築すると、このアイテムが無視できないコストであり、あなたは アイテムの内容が将来独立してさまざまに変わると予想される 関連するテストコードのまたは、関連するテストコードとは無関係に変わります。 テスト中のシステムの異なる構成について。その場合は、最適に取得します の実行時パラメータで選択できるファイルまたはその他のソースからの項目 テストスイート。 Googletestでは、::testing::Environmentをサブクラス化することがAです テストスイートリソースのパラメータ化獲得のための設計設計

現実の場合の場合、テストデータ項目の内容は緩やかに結合されます。 関連付けられたテストコード、それをテストケースにハードコーディングすることはほとんどありません 慎重な選択になるために。他の種類のランタイムとは対照的に、テストファイル コンフィギュレータは、それらがバージョン管理できる貴重なプロパティを持っています。 ソースコードと同じシステム。)

テストデータ項目の内容がの内容がの場合 関連付けられたテストコードその後、私はそれを抽出するのではなく、それをハードコードするためにバイアスされています データファイルから。ただ偏って、原理的では献身的ではありません。たぶんあなたのテスト スイートは、Public APIテストデータを初期化するための堅牢なライブラリーサービスを採用しています。 と言って、テスト管理と欠陥管理にも引っ掛けられたXMLファイル、 システム罰金!

テストデータのファイルがプライマリである場合 テストリソース - テストスイートが生成できないもの - その内容 有能なメンテナがすぐに理解できるテキストデータであることが最善でした そして操作する。この設定ではもちろん、 C / C ++ Hex定数のリストは、たとえばテキストデータです。 ソースコード。テストファイルにバイナリまたは厄介なデータが含まれている場合 それから、テストスイートは読みやすいその生産の手段を最もよく含んでいました 一次リソーステストスイートが依存するのは避けられないことがあります 外部からの「Archetypal」バイナリであるが、それらはほぼ必然的に伴う テストエンジニアとバグ修復担当者の厳しい景色は、16進編集者の前で灰色を回します。

主なテストデータがメンテナに読みやすいという原則を考えると、 プライマリテストデータが「ある種のコード」になるというノルムとしてそれを取ることができます。 ロジックフリーになるが、プログラマーがそのプログラマーの種類のものになるでしょう 測量と編集に慣れています。

4096 64ビット符号なし整数の特定のシーケンスを想像してみる (大きなマジックテーブル)はあなたのソフトウェアをテストするために必要であり、しっかりと 関連するテストコードに勤務しています。それは巨大なベクトルや配列としてハードコーディングすることができます Test Suiteのソースファイルの初期化リストリスト。かもしれない CSV形式またはINで維持されているデータファイルからテストスイートによって抽出された CSV句読線

データファイルからの抽出とハードコーディングから、それは促すことができます (Andrew McDonellの答えによると)この貴重ではの脱退を達成すること 同じ内の他のコードの改訂からのBMTへの修正 ソースファイル。同様に、そのフレームのソースコードであれば促されるかもしれません 巨大なリテラル

初期化は不可能なものになる傾向があり、したがってメンテナンスを行います 責任。

しかし、これらの両方の点は、定義する観察に対抗するかもしれません BMTの宣言は、それ自体のすべてのソースファイルでコーディングされる可能性があります。それ テストデータの初期化がテストスイートのコードレビューポリシーになる可能性があります。 を描く必要があります - そしておそらく独特の命名を守るファイルに コンベンション。確かに狂信的な方針、しかしそれ以上の狂信的ではありません すべてのテストデータのイニシャライザをファイルから抽出する必要があると主張するものとします。 メンテナがBMTを調査する義務がある場合は、それをすべて含まれています。 ファイル拡張子がclass ::testing::Environment.cppであるかどうかは違いはありません。 何でも:すべての問題は「コード」の理解可能性です。

データファイルからの抽出およびデータファイルからの抽出に対して促すことができます データファイルからの抽出は無関係の源を導入する必要があります テストケースへの潜在的な失敗 - すべてのが起こるべきではありませんエラー ファイルから正しいデータを読むことを敗北する可能性があります。これはオーバーヘッドを課します 本物のテスト失敗との正しい区別と明確な区別を与えるための開発をテストする ファイルからテストデータを取得し、可能な限り明確に診断するための失敗 後者の原因

Googletestと同等の機能的フレームワークの場合、この点は 多形フィクスチャベースクラスに備えている程度に対抗する .dat::testing::Testのように。これらが促進されます テストケースにおけるテストリソースの取得をカプセル化する際のテスト開発者 またはテストスイートの初期化が正常に終了するか、または 診断された失敗を伴う、あらゆるテストケースの構成テストが実行される前に実行されます。 RAIIは、セットアップ障害と実際の失敗との間の不課題の分割を維持することができます。

データファイルの既知のファイル処理のオーバーヘッドがあります route 枠組みのRAII機能が機能する運用上のオーバーヘッドがあります 削減することは何もしません。対応するHEFTYテストシステムとの取引で データファイル、データファイルよりも操作上のミシャップに起動しやすい 存在しなければならないソースファイルは、ビルド時に正しいです。 データファイルは、実行時に欠落しているか、または誤って表示される可能性が高い、または 不正なものを含む、またはどういうわけか許可が拒否された、または どういうわけか間違った改訂に現れる。テストシステムにおけるそれらの用途 ソースファイルのものと同じくらい簡単ではなく、厳密に制御されています。 もの テストデータファイルに起こっていることは起こるべきではありません。ファイルの操作上の摩擦の一部です。 それらに頼ってそれらの数に比例するテストシステム。

ソースファイルはテストデータの初期化を衛生的にカプセル化できます。 改訂追跡のために、それらを抽出するためにそれらを抽出することができる プリプロセッサがコンパイルの副作用として抽出を行うファイル。 その点で、なぜ追加の負債を採用して、それを抽出するのですか? テスト管理の推奨されるXMLインタフェースのように、良い答えがあるかもしれません。 欠陥管理システムですが、「テストデータは、それをハードコードしないように」は良いものではありません。

テストスイートが以下のシステムのさまざまな構成をサポートしている場合でも データがデータの場合、テストデータ項目のさまざまなインスタンス化を呼び出すテスト アイテムはのビルド構成で説得力があります。 まだまだ(衛生的に)ハードコードし、条件付きコンパイルを選択してください 右のハードコーディング。

これまでのところ、私は修正追跡衛星の議論に挑戦していません テストデータイニシャライザのファイルベースの分離のために。私はちょうどをしました イニシャライザがハードコードされている通常のソースファイルができることを示す この分離を達成します。そして私はその議論を踏まなければならなかったが データイニシャライザをテストするという狂信的な結論の短い停止を止めたい 原則として常に専用のファイルから抽出されるべきです - ソースファイルまたはデータファイルかどうか。

この結論に抵抗する理由をベラボールする必要はありません。そのように 平均的なピザの食べるよりもわかりやすい現地のテストコードにあります プログラマーは、成長したテストスイートファイルの書き込みおよび組織化 心が必要か健康的であるよりもはるかに早く、正常に テストスイートのすべてのプライマリリソースは「ある種のコード」です。 A. プログラマーのスキルセットには、ファイルへの分割コードのスキルが含まれています 適切な改訂追跡衛星を確保するための適切な粒度を持つ。 それは機械的な手順ではありません、それはカバーするコードレビューのための専門知識です。 コードレビューは、テストデータの初期化を確実にすることができます。 彼らは達成され、よく設計され、巧妙に設計され、巧妙に修正された改訂追跡 他のすべての日常的な尊重のように。

下線:テストスイートの同じビルドを実行できるようにしたい場合

いろいろ これらのモックネットワーク応答のうち、ファイルからそれを読みます。一方でそれをそれをあれば テストスイートのビルド構成と不変または共変動、なぜハード コードする?

他のヒント

(警告 - この回答は任意の単体テストフレームワークに一般的です)

私はテストデータファイルをリビジョン制御システムで別々のオブジェクトとして保持することを好みます。これにより、以下の利点があります。

  • 様々な状況をテストするために、ユニットテストをコーディングすることができます。
  • 必要に応じてデータの変更を追跡できます

単体テストの実行が必要条件を読み取らない場合は、いくつかの状況で必要な条件になる可能性がある場合は、Fixture Setupでベクトルを初期化するC ++コードを生成するプログラムまたはスクリプトを作成することを選択できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top