2

Delphi 2010 に付属の DUnit を使用して、適切な OO プラクティス (例: ビジネス ロジックをクラス/ユニットに分離する) に従わない 1000 万の LOC プロジェクトにいくつかの基本的な自動テストを実装しようとしています。通常のユニットは実行できません。ビジネス ロジックの各部分は相互に依存する数十のユニットにまたがっているため、このプロジェクトでテストを行っていますが、これらのユニットの「グループ」は、特定の「メイン ビジネス ロジック画面」を中心にしています (例: すべての請求書ロジック関連のユニットは、これらの画面はクラスであるため、単体テストの代わりに「メイン ビジネス ロジック画面クラスのテスト」を行うことができますが、これらの「メイン画面」には、プロセスの起動時に作成される多くのものがまだ必要です。

だから私は両方が必要です:

  • 悪いプロジェクトのスタートアップを実行できるようにする
  • そのオブジェクトにアクセスできる

悪いプロジェクトには、オブジェクトにアクセスするためにキャストできるポインターを返すエクスポートされた関数が既にいくつかありますが、どちらの方法でも呼び出すことができません。

問題のあるプロジェクトをテスト プロセスの子プロセスとして作成すると、スタートアップ コードは正常に実行されますが、複雑な IPC メソッドや問題のあるプロジェクトの構造を大幅に変更しない限り、エクスポートされた関数を呼び出す方法が見つかりません。

悪いプロジェクトの .exe を LoadLibrary 関数のように dll としてロードした場合、悪いプロジェクトによってエクスポートされた関数を呼び出すと、この単純な手順でもアクセス違反やセグメンテーション エラーが発生します。

procedure Test; {safecall;} {stdcall;}
begin
  showmessage('Yay!');
end;

どうすれば両方を行うことができますか?

4

2 に答える 2

3

あなたが話しているアプローチ(エクスポートされた関数を使用する)はうまくいきません。2 つの Win32 プログラム間の通信の最も簡単な形式は、SendMessage または PostMessage を使用して相互に通信することです。ステップ 1 でウィンドウ ハンドルを (通常はウィンドウ クラス名で) 見つけ、メッセージを送信するのがステップ 2 です。

第 2 に、DUnit では目的に近づくことができません。また、TTestCase を GUI コントローラーとして適切に拡張することはできません。単体テスト用です。丸ペグ、角穴。ハイブオフしてテストできるクラスの TTestCases を記述し、DUnit を使用して、テスト カバレッジを提供できるシステムの部分のテスト カバレッジを提供します。

UI テストには、完全に別のフレームワークを使用します。あなたが提案している種類の自動化された統合テストのために、Delphi プログラマーによって行われる 2 つの基本的なアプローチがあります。

  1. カスタム ハック ジョブ。あなたが説明しているのはそのようなものです。Embarcadero の内部には、 Zombieと呼ばれるフレームワークが存在します。、Nick が 2007 年にブログで書いたものです。そのアプローチは、いくつかの種類の「プリミティブ IPC」に基づいており、通常、プログラムの外部からプログラム内のコントロールのウィンドウ ハンドルへの Win32 SendMessage または PostMessage ウィンドウ メッセージを含みます。ただし、内部コードはゾンビ テストを許可するために大幅に変更されています。いいえ、Teh Codez を使用することはできません。これらは Embarcadero の内部および所有物です。しかし、このアプローチがうまく機能し、単体テストのようにアプリケーション全体を書き直したり、膨大な数のモッククラスを作成したりする必要がないことを示しています。ハック ルートをたどりたい場合は、独自のユーザー インターフェイス テスト フレームワークを作成することになります。これは、おそらく DUnit コードとは完全に分離され、使用されていないはずです。試してみてください。重大なインピーダンス不整合。私が 2013 年に独自のカスタム フレームワークを開始した場合、それは DCOM ベースになります。Delphi DCOM サーバー コードは条件付きで多くのプログラムに単純にコンパイルでき、DCOM は関数呼び出しの「マーシャリング」の詳細を処理するからです。私はプロジェクトに 1 年かかると思いますが、あきらめるでしょう。最終的には、どんなシステム (DCOM または Win32 メッセージ ベース) も成果を上げられるかどうか疑わしいからです。

  2. AutomatedQA/SmartBear TestComplete のような、テスト スクリプトを記述する完全な外部テスト ツール。テストは Delphi テスト プログラムにコンパイルされませんが、TestComplete 内で実行されます。Pascal に似たスクリプト構文は、テスト スクリプトを作成するための利用可能なオプションの 1 つにすぎません。

于 2013-02-04T21:13:47.377 に答える
1

ここでも同じ問題が発生しています。エクスポート関数を機能させるには、デルファイライブラリプロジェクト(* .dll)が本当に必要なようです(実行可能ファイルで関数を直接呼び出す場合、フレームワークの初期化は行われないと思われます。保証はありません)。

注:まだDelphi 5を使用しているため、ここではdunitの統合は行いません。

私たちが使用した解決策は、条件付きDEFINEを使用してdunitソースをプロジェクト(.exeプロジェクト)に追加し、スタートアップユニットでこの条件付き定義を使用することです。

アプリケーションのスタートアップコードの例:

  if ComServer.StartMode <> smAutomation then
  begin
    OurApplication.Login ;
  end;
{$IFDEF _AS_TESTRUNNER_}
    GUITestRunner.RunRegisteredTests;
{$ELSE}

  if OurApplication.HasStartCommands then
  begin
    Application.ShowMainForm := False ;
  end
  else begin
    if ComServer.StartMode = smAutomation then
      Application.ShowMainForm := False
  end;

  Application.Run;
{$ENDIF}

  OurApplication.Finalize;

_AS_TESTRUNNER_条件付き定義を使用する場合、アプリ(およびdb接続)が初期化されるように、最初にログインする必要があります。DUnitのGUITestrunnerをbijに従ってください。

テストケースは、例とまったく同じように初期化部分に登録できます。

チャームのように機能します。

于 2013-02-21T17:03:13.037 に答える