3

背景:継承して拡張している複雑なアプリケーションがあります (大学院の研究プロジェクト)。再編成が保守性と使いやすさに長期的にプラスの影響を与えることを確認したいです。つまり、コードに取り組む可能性のある将来の人々のために、可能な限り標準的な方法で物事を設定することを確認したいと考えています。アプリケーションを完全に再構築する時間はありませんし、自分の居場所でもありません。

アプリケーションはエコシステム モデルです。これは、重労働を行う C++ で書かれた共有ライブラリで構成されています。このライブラリは、シミュレーションを「駆動」する Java アプリケーションに含まれており、データベース I/O を処理し、GUI を提供します。

開発の過程で、実行時に (コードの C++ 部分から直接) コンソールに内部変数を便利に出力するために、多くのユーティリティ関数をプロジェクトに追加しました。

現在、これらの関数をユーティリティ ファイル (ヘッダーと cpp) に分解し、必要に応じて他のファイルに含めています。次の例に従って、関数を独自の名前空間に配置しました: Organizing utility functions in C++

質問:モデル全体を再コンパイルおよび変更/実行せずに開発および実験できるように、ユーティリティ関数のテストを書きたい場合、これらのテストはどこにどのように含めるのが最適ですか?

util.cpp ファイルに main() 関数があると問題になりますか? 驚いたことに、これを試したところうまくいきました。util.cpp ファイルを個別にコンパイルして実行できます。また、util.cpp を含む主要なアプリケーションも正常にコンパイルおよび実行されます。2 番目の main() の存在が問題になると思っていたので驚きました。ただし、アプリケーションのエントリ ポイントは Java コードにあります。

ただし、これが最適なルートかどうかはわかりません。この戦術の将来の落とし穴を見るのに十分な経験がありません。

これは、私の util.cpp ファイルの短い例です。

#include "util.hpp"
#include <iostream>
#include <vector>
namespace util {
  /** Prints a std::vector of doubles in a format that can be 
  * copied directly into a python console. */
  void util::pyprint_vec(const std::vector<double> & v){
    std::cout << "[";
    for(std::vector<double>::const_iterator it = v.begin(); it != v.end(); ++it){
      std::cout << *it << ", ";
    } 
    std::cout << "\b\b]"; // remove the last comma
  }
}

int main() {
  using namespace util;
  using namespace std;

  cout << "Testing some of the utility functions...\n";
  vector<double> a_vec(50,12.0);
  pyprint_vec(a_vec);
  cout << endl;

  return 0;
}

最終的には、一部の関数をテンプレート化し (その時点で、実際には util.hpp に移動します)、ファイルに追加し、他のプロジェクトで使用できるようにすることを想定しています。アドバイスをよろしくお願いします。

4

2 に答える 2

2

通常、単体テストを含み、テスト対象の関数にリンクする別の実行可能プログラムを作成する必要があります。たとえばutil_test.cpp、main() 関数とテストを含むコードを含む を作成し、util.hpp を *#include* することができます。コンパイル時には、テストするコードへの静的リンクまたは動的リンクを使用します。

技術的には、util.cpp に main() 関数があっても問題ありません。ただし、ライブラリの別の場所に 2 番目のメイン関数を含めて (他の何かを単体テストするため)、それを同じ共有オブジェクトにリンクすると、リンカー エラーが発生します。

メイン関数には、リンカーが実行可能ファイルを作成するときに特別なコードを挿入する以外に特別な意味はありません。これにより、プログラムを開始すると、メインのコードが実行されます。「共有オブジェクト」ライブラリをロードすると、プログラムが「開始」されず、メイン関数を明示的に呼び出さない限り、そのコードは実行されません。

于 2012-06-14T19:52:36.930 に答える
1

純粋に機能させるという観点からは、メイン関数は 1 つあれば問題ありませんが、起動時に呼び出すことができるのは 1 つだけであるため、2 つあるとコンパイルが中断されます。

cppunitcxxtest (私の現在のお気に入り)などの単体テスト フレームワークを調べたいと本当に思っています。これらは、単独で行おうとすると再実装が不十分であることに気付く機能を提供します。複数の実行可能ファイルを生成するのは敗者ゲームです。コードベースのサイズに関係なく、コンパイルに永遠に時間がかかります。ある種のフレームワークによって駆動されるコンパイル済みの実行可能ファイルが 1 つ必要です。

于 2012-06-14T20:20:55.860 に答える