Dunit GUIテスト:別の「フォーム」に「アプリケーション」を強制することはできますか?
-
29-10-2019 - |
質問
Dunitを使用してGUIユニットテストを実行しようとしています。そのアプリケーションは、MainFormがそれ自体に動的にフレームを作成するアプリケーションです。テストケースのフォームとしてアプリケーションへのテストのメインフォームを作成し、メニュー項目などにアクセスすることができました。
問題は、アプリケーションがフレームを動的に作成しようとするときに発生します。フレームのリソースの読み取り値は、ウィンドウハンドルが必要なポイントになります(私の場合、タブシートのキャプションを設定します)。ここでは、twincontrol.gethandleからtwincontrol.createwndおよびtcustomframe.createparamsに移動します。
このcreateparamsでは、コードは次のように述べています。
if Parent = nil then
Params.WndParent := Application.Handle;
これが違いが発生する場所です。実際のアプリケーションを実行すると(テストではありません)、アプリケーション。ハンドルはゼロ以外の数値を返し、フローは継続されます。ただし、Dunitテストアプリケーションでは、アプリケーションのハンドルは0を返します。これにより、Twincontrol.createwndのコードが原因になり、フレームには親がいないことを示す例外が発生します。
with Params do
begin
if (WndParent = 0) and (Style and WS_CHILD <> 0) then
if (Owner <> nil) and (csReading in Owner.ComponentState) and
(Owner is TWinControl) then
WndParent := TWinControl(Owner).Handle
else
raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);
テストのためだけに「生産」コードを変更せずに、この問題(および一般的にすべてのテストの問題)を回避したいと思います。 「アプリケーション」を他の何かに強制することができるか、それとも他の方法でこれを回避できるかどうかについての手がかりを提供できますか?
コードを見ると、他の回避策のシナリオは、所有者(アプリケーションへの「私の「メインフォーム」」、つまり、ハンドルを手に入れたいと思う人)を獲得しようとすることです。このフレーム作成はテストで作成されますが、少なくとも最初はこれを実現するのはそれほど簡単ではないようです。
解決 2
すべてのコメントと返信をありがとう!私は問題を解決したと信じていますが、少なくともこれまでに発見されたものです。以下の私の調査結果と最終的な状況を要約します(他の誰かがこれが有用であると思われる場合)。
ttestsetupから継承するテストデコレータクラスがあります。これは、必要に応じて作成するダミー(メイン)フォームへの参照を保持しています。
また、このようなアプローチを使用して、ランタイムでapplication.mainformを切り替える方法を見つけました。 http://www.swissdelphicenter.ch/torry/showcode.php?id=665
テストデコレーターのセットアップ方法では、最初にダミーフォームを作成し、次にアプリケーションの主要なフォームとして設定します(この設定はここでは必要ない場合があります)。
次に、テストケースクラス(TGuiteStcaseから継承)を行います。そのセットアップと断片が各テストで実行されます。このセットアップでは、テストしているメインフォームを作成し、アプリケーションのメインフォームとして設定します。その後、テストケースの断裂でテストした後、ダミーフォームを再びアプリケーションの主要な形式に設定し、この呼び出しの後にテストしているメインフォームに自由になりました。それ以外の場合は、現在アプリケーションであるフォームを解放します。
他のヒント
Application.Handleを設定する方法を回避する代わりに、TFORMを作成し、Frame.ParentをそのTFormに設定する必要があります。
//Dunit Test Scaffolding code...Set up a workable environment for the test:
aForm := TForm.Create(nil);
aFrame := TFrame.Create(aForm);
aFrame.Parent := aForm;
実際のアプリでは、フレームには親があります(通常、窓に親になりますか、通常はtformまたはtpanel)。親なしで実行するようにフレームを伝えようとしています。これは、TFRAMEが行うようには設計されていません。