2013-02-04 102 views
2

我試圖在一個1000萬的LOC項目上執行一些基本的自動化測試,這些測試不遵循良好的面向對象的實踐(例如:將業務邏輯分爲類/單元)和Delphi 2010一起使用的DUnit。我無法做到所有發票邏輯相關單位都集中:在這個項目上,因爲業務邏輯的每個部分橫跨幾十個相互依存的單位蔓延正常的單元測試,這些單位的「羣體」,然而,圍繞特定的主要業務邏輯屏幕'(前中心主發票屏幕上),由於這些屏幕是類我可以做的主要業務邏輯屏類測試「,而不是單元測試,但這些「主屏幕」還需要很多的是在進程啓動時創建的東西。在delphi中訪問其他.exe數據的最簡單方法是什麼?

所以我需要兩個:

  • 能夠運行的不良項目的啓動東西
  • 能夠訪問其對象

壞項目已經具備了一定的導出函數返回指針,我可以投來訪問它的對象,但我不能給他們打電話兩種方式:

如果我創建壞項目作爲測試PR的子進程啓動代碼運行良好,但是我找不到一種方法來在沒有複雜的IPC方法的情況下調用導出的函數,或者對不良項目的結構進行重大改變。

如果我加載壞項目的.exe作爲一個DLL與LoadLibrary函數,調用由不良項目的結果在訪問衝突和/或段錯誤的錯誤,即使這個簡單的程序導出的任何功能:

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

我怎樣才能做到這一點?

+0

如果您不能編寫代碼在被測程序中運行,那麼您需要IPC。 –

回答

3

你正在談論的方法(使用導出的函數)不會飛。兩個Win32程序之間最簡單的通信形式是讓它們使用SendMessage或PostMessage來相互交談。找到窗口句柄(通常通過窗口類名稱)是步驟1,發送消息是步驟2.

其次,DUnit讓你無法靠近目標,並且TTestCase不能很好地擴展爲GUI控制器,因爲這不是它是爲了什麼。它用於單元測試。圓釘,方孔。爲您可以關閉和測試的類編寫TTestCases,並使用DUnit爲您可以提供測試覆蓋的系統部分提供測試覆蓋。

對於UI測試,請使用完全獨立的框架。 Delphi程序員有兩種基本方法可以對您提出的排序進行自動集成測試。

  1. 定製的黑客工作。這就是你所描述的。在Embarcadero內部,存在一個叫做Zombie的框架,這個框架是在2007年尼克博客上發表的。它的方法基於幾種「原始IPC」,通常涉及從程序外部到窗口句柄的Win32 SendMessage或PostMessage窗口消息程序內部的一個控件。但是,內部代碼被明顯修改以允許殭屍測試。不,你不能擁有Teh Codez,它們是Embarcadero的內部和專有的。但它確實表明,該方法不工作,並且不需要重寫整個應用程序或編寫模擬類的數量龐大,像單元測試 會做。如果你想遵循黑客路線,你將會編寫自己的用戶界面測試框架,它應該完全獨立於並且不使用DUnit代碼。歡迎您嘗試,但我告訴你,這是一個嚴重的阻抗不匹配。如果我在2013年開始自己的自定義框架,它將基於DCOM,因爲Delphi DCOM服務器代碼可以簡單地被有條件地編譯到許多程序中,並且DCOM將爲您處理函數調用「編組」的細節。我懷疑我會在項目中花費一年的時間,而且我會放棄,因爲最終,我懷疑我可以讓任何系統(基於DCOM或Win32消息的)得到回報。

  2. 一個完整的外部測試工具,您可以在其中編寫測試腳本,如AutomatedQA/SmartBear TestComplete。您的測試不會被編譯到delphi測試程序中,而是在TestComplete中運行,類似Pascal的腳本語法只是編寫測試腳本的可用選項之一。

+0

當我說我想測試屏幕時,我不是指UI,而是屏幕(表單)的類,因爲每個屏幕都有它自己的類。另一件事是,我不需要將不良項目用作流程,我只需要能夠訪問其導出的函數並同時運行其啓動內容。 –

+0

我明白你的意思,但我想說你的願望是困惑和瑕疵,並且不會奏效。如果你想測試類,你的工具是單元測試,模擬,接口,依賴注入等,而不是DLL黑客。 –

1

我們在這裏有同樣的問題。看起來你確實需要一個delphi庫項目(* .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_有條件的定義,我必須先登錄,從而使我們的應用程序(和數據庫連接)得到初始化。緊隨其後的是杜伊特的GUITestrunner。

測試用例可以在初始化部分完全註冊,如示例中所示。

工程就像一個魅力。

相關問題