2012-02-22 10 views
6

DUnit ile bir GUI birim sınamasını, ana formu dinamik olarak çerçeveler oluşturmaya çalışan bir uygulamaya çalıştırmaya çalışıyorum. Uygulamada sınama uygulamasının ana formunu sınama durumunda bir form olarak oluşturabildim ve menü öğelerine vb. Erişebildim.DUnit GUI Test: 'Uygulamayı' farklı bir 'forma' zorlayabilir miyim?

Sorun, uygulama dinamik olarak bir çerçeve oluşturmaya çalıştığında ortaya çıkıyor. Çerçevenin kaynak okuması, pencere tanıtıcısına ihtiyaç duyduğu bir noktaya gelir (benim durumumda, bir sekme sayfasının altyazısını ayarlama). İşte TWinControl.GetHandle'den TWinControl.CreateWnd ve TCustomFrame.CreateParams'a gider. Bu CreateParams yılında

, kod diyor ki:

if Parent = nil then 
    Params.WndParent := Application.Handle; 

fark meydana yerdir. Gerçek uygulamayı çalıştırdığımda (testte değil), Application.Handle burada sıfır olmayan bir sayı döndürür ve akış devam eder.

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]); 

İsterdim Ama Dunit testi yapılırken, Application.Handle Buradaki çerçeve bir ebeveyni olmadığını bildiren bir istisna yükseltmek TWinControl.CreateWnd kod neden 0. döndürür Sadece testler nedeniyle "üretim" kodunu değiştirmeden bu problemi (ve genel olarak tüm test problemlerini) aşmaya çalışın. "Uygulamayı" bir şekilde başka bir şeye zorlayabileceğimi veya başka bir şekilde bu konuda çalışıp çalışamayacağına dair herhangi bir ipucu verebilir misiniz?

Kod bakıldığında, olası bir diğer geçici senaryo senaryonun sahibi olmak için (ki bu da benim testim için "MainForm", yani tanıtıcıdan almak istediğim) csHızda bu çerçeveyi oluştururken okuma durumu, ancak en azından başlangıçta bunun gerçekleşmesi çok basit görünmez.

+0

Sizin dpr'niz bir Application.Initialize var mı? Belki de bu sapı ayarlar. – mjn

+0

Hem test uygulamam hem de gerçek uygulamada, dpr'lerinde Application.Initialize var. Application.Handle'ın bir şeye ayarlanmış veya bulunmadığı bir yer bulabileceğimi görmek için başlatmaları adım adım deneyebilirim. – DelphiUser

+0

DUnit, bir GUI'yi test etmek için en iyi değil gibi görünüyor. – GolezTrol

cevap

0

Tüm yorumlar ve cevaplar için teşekkürler! Sorunları çözdüğüme inanıyorum, en azından şimdiye kadar bulunanlar. Bulgularımı ve son durumumu aşağıda özetleyeceğim (bir başkasının bunu yararlı bulabileceği durumlarda).

Gerektiğinde oluşturduğu bir kukla (ana) forma referans veren TTestSetup'dan devralınan bir test dekoratör sınıfım var. İlk sahte bir şekilde oluşturmak Test dekoratör SetUp yöntemde http://www.swissdelphicenter.ch/torry/showcode.php?id=665

ve daha sonra uygulama ana formu olarak ayarlamak:

Ayrıca bu gibi bir yaklaşımı kullanarak çalışma ile Application.MainForm geçmek için bir yol bulmuş (Bu ayar burada gerekli olmayabilir). Daha sonra her test için SetUp ve TearDown tarafından çalıştırılan bir test vakası sınıfına (TGUITestCase'den miras alma) sahip bir test sınıfım var. Bu Kurulumda, test ettiğim ana formu oluşturup Uygulama'nın ana formu olarak ayarlıyorum. Sonra test vakasının TearDown testinden sonra, kukla formunu Uygulamanın ana formu olarak tekrar test ettim ve bu aramayı test ettiğim ana forma Yakın ve Serbest bıraktıktan sonra. Aksi takdirde Application.MainForm olan bir formun serbest bırakılması tüm DUnit uygulamasının sonlandırılmasına neden olur.

+0

Bu sizin için işe yarıyor olsa da, hala TFrames bir yanlış kullanımdır. –

2

ApplicationHandle'ı ayarlamak için bir yol bulmak yerine, bir TForm oluşturmalı ve frame.parent'ınızı bu TForm olarak ayarlamanız gerekir.

//Dunit Test Scaffolding code...Set up a workable environment for the test: 
aForm := TForm.Create(nil); 
aFrame := TFrame.Create(aForm); 
aFrame.Parent := aForm; 

gerçek uygulamalarda, çerçeveler bir ebeveyn olacak (pencere, genellikle TForm veya TPanel için ebeveynli bırakılır). Bir çerçevenin bir ebeveyn olmadan çalışmasına, TFrame'nin yapmak için tasarlanmadığını söylemeye çalışıyorsunuz.

+0

Aslında, bir çerçeveyi bir ebeveyn olmadan çalıştırmaya çalışmıyorum, sadece oluştur. Gerçek uygulamamda, çerçeveler öncelikle ana biçim olarak Sahip olarak oluşturulur. Daha sonra belirli seçimler yapıldıktan sonra, seçime bağlı olarak uygun bir çerçeve seçilir ve bu çerçeve ana formunda bir üst öğe olarak ana öğeye sahip olacak şekilde ayarlanır. Böylece, tüm kareler aynı üstte, birer birer ile görüntülenecek, ancak önceden oluşturulacak. Tüm bunlar, üretim sınamında, yalnızca sınama uğruna değiştirmek istemediğim bir şey olur. – DelphiUser

+0

TFrame'in yaptığınız bu şeye izin vermek için tasarlandığını düşünmüyorum. Sadece bir sınır oluşturmadan bir Form oluşturmalı ve yerleştirmelisiniz ve böyle bir sorun yaşamayacaksınız. Bu durumda davasında bir çerçeve yapmanın SIFIR FAYDASI. –

+0

Çerçeveler kullanırken, herhangi bir yerleştirme sorununu dikkate almak zorunda değilim, bu yüzden en azından benim için sıfır olmayan bir yarar var. – DelphiUser