ããŒã1ããŒã2ããã«ã¡ã¯ã
ãã®èšäºã§ã¯ãVCLã³ãŒããFireMonkeyã«ç§»æ€ããããã»ã¹ãèªè
ã«çŽ¹ä»ããŸãã ããŒãžã§ã³2009ããã®ç§ã®æèŠããå§ãŸãæšæºã®Delphiããã±ãŒãžã§ã¯ã
DUnitãããžã§ã¯ããããã«äœ¿çšã§ããŸãã
ãã ããVCLã«ãã£ãŠå€ä»£ã«æžãããŸããã ãŸããFireMonkeyçšã«èšè¿°ãããã³ãŒãããã¹ãããããšãã§ããŸãïŒã³ã³ãœãŒã«åºåã®ãããïŒ ãä»ãããèµ·åããŸãã
DUnitã«ç²ŸéããŠããããŸãã¯ã»ãšãã©ç¥ããªã人åãã éåžžã®ã¢ãŒãã§ã¯ãããã¥ã¡ã³ãã§ã¯ãFile-> New-> Other-> Unit Test-> TestProjectã®å®è¡ãæšå¥šãããŠããŸãã 次ã«ãGUIãŸãã¯ã³ã³ãœãŒã«ãªãã·ã§ã³ãéžæããå¿
èŠããããŸãã ãããã®ããã»ã©è€éã§ã¯ãªãæäœã®ãããã§ãGUIçšã«æ¬¡ã®ãããªïŒå°ãªããšããç§ã®ãXE7ããŸãã«ãã®ã³ãŒããçæããïŒæ°ãããããžã§ã¯ããã§ããŸãã
program Project1Tests; {$IFDEF CONSOLE_TESTRUNNER} {$APPTYPE CONSOLE} {$ENDIF} uses DUnitTestRunner, TestUnit1 in 'TestUnit1.pas', Unit1 in '..\DUnit.VCL\Unit1.pas'; {$R *.RES} begin DUnitTestRunner.RunRegisteredTests; end.
次ã«ãTestCaseãè¿œå ããŸãããããè¡ãããŸãïŒãã¡ã€ã«->æ°èŠ->ãã®ä»->åäœãã¹ã-> TestCaseïŒãçµæã¯æ¬¡ã®ããã«ãªããŸãã
unit TestUnit1; interface uses TestFramework, System.SysUtils, Vcl.Graphics, Winapi.Windows, System.Variants, System.Classes, Vcl.Dialogs, Vcl.Controls, Vcl.Forms, Winapi.Messages, Unit1; type
äžè¬ã«ãç§ã®äŸã¯ãDelphi7ã§ãã£ãŠããã¹ããè¿œå ããããšãã©ãã»ã©ç°¡åãã瀺ããŠããŸãã å¿
èŠãªã®ã¯ãDUnitTestRunner.RunRegisteredTestsãåŒã³åºãããšã ãã§ãã ãããŠãTestCaseã§æ°ãããã¡ã€ã«ããããžã§ã¯ãã«è¿œå ããŸãã 詳现ã«ã€ããŠã¯ãDUnitã䜿çšãããã¹ãã®åé¡ã«ã€ããŠèª¬æã
ãŸã ã
å®è£
ã®ããã«ãDUnitãå®è¡ãã人ãç¹°ãè¿ãå¿
èŠããããšå€æããŸããã
ç§ãééããæåã®åé¡ïŒTTreeNodeãšTTreeViewItemã¯ããŸã£ããå
åŒã§ã¯ãªãããšããäºå®ãããç§ã¯èšããŸãããããã¥ã¡ã³ãã¯å
šå¡ãæããŸãïŒïŒ
type TfmGUITestRunner = class(TForm) ... protected FSuite: ITest; procedure SetSuite(Value: ITest); ... public property Suite: ITest read FSuite write SetSuite; end; procedure RunTestModeless(aTest: ITest); var l_GUI: TfmGUITestRunner; begin Application.CreateForm(TfmGUITestRunner, l_GUI); l_GUI.Suite := aTest; l_GUI.Show; end; procedure TfmGUITestRunner.SetSuite(Value: ITest); begin FSuite := Value;
åé¡ã¯ããã€ãã®ããã«ããããã°ããŸãã¯ããã¥ã¡ã³ãã§ãèªèããããŠããŸã:)ã FireMonkeyã§ã¯ãApplication.CreateFormïŒïŒ;ã¯ãã©ãŒã ãäœæããŸããã ã¯ããå¥åŠãªããšã«ã
TApplication.CreateFormç§ãèŠã€ãããšãã®ã³ãããã«é¢ããç§ã®ã³ã¡ã³ã:)FSuiteããŸã äœæãããŠããŸãããApplication.CreateFormã¯ãå®éã«æ瀺çã«ããã¯ããªãå Žåããéç¬ãéåžžã®ãã©ãŒã ãäœæãããå°æ¥ã®ã¯ã©ã¹ãžã®ãªã³ã¯ã®ã¿ãäœæããŸãã ãããã£ãŠãããã¯ããŸã£ãããªãã¯ã©ã¹ã¡ã³ããŒã«åœ±é¿ããŸãã
AVã¯System._IntfCopyïŒvar DestïŒIInterface; const SourceïŒIInterfaceïŒ;ã«ã¯ããŒã«ããŸãã
ãããŠãDestã«ãã¿ããããã€ã³ã¿ãŒãã§ã€ã¹ãnilã§ã¯ãªãããã«åºãŠããŸãã ãããŠãããã¯ãåã®ã€ã³ã¿ãŒãã§ã€ã¹ïŒ// nilã§ãªãå ŽåïŒã§1ãæžç®ãããšãã«è¡šç€ºãããŸãã
ãããªè¡ãæžããŠãããããšã§ã
FSuiteïŒ= nil;
ãã®ããŒãã«é¢ããå¥ã®
ãªã³ã¯ã次ã«ç€ºããŸã-ã ããã¯èšãããšãããŸããïŒ æ£çŽã«èšããšãMake Formãšããã¡ãœããããããããªããšããäºå®ã«ãå°ãã·ã§ãã¯ãåããŸããã
ãã©ãŒã ãæ瀺çã«äœæããŠåé¡ã解決ãïŒl_GUIïŒ= TfmGUITestRunner.createïŒnilïŒ;ïŒã次ã«é²ã¿ãŸãã
次ã«ããã¹ãçšã«è¿œå ãããTestCaseã«åºã¥ããŠãã¹ãããªãŒãæ§ç¯ããå¿
èŠããããŸãã ãæ°ã¥ãã®æ¹ã¯ããã©ãŒã ã®äœæããã»ã¹ã¯RunRegisteredTestsModelessã¡ãœããããå§ãŸããŸãã
procedure RunRegisteredTestsModeless; begin RunTestModeless(registeredTests) end;
ãã®ã¡ãœãããDUnitã®äœæè
ãªã©ã®å¥ã®ã¢ãžã¥ãŒã«ã«é
眮ããªãããšã«ããŸããããã®ãããfmGUITestRunnerãæ¥ç¶ããã«ã¯ããããžã§ã¯ãã³ãŒãã§ã¢ãžã¥ãŒã«ãæå®ããå®éã«ç®çã®ã¡ãœãããåŒã³åºãå¿
èŠããããŸãã ç§ã®å Žåããããžã§ã¯ãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
program FMX.DUnit; uses FMX.Forms,
æ°é
ãã®ããèªè
ã¯ãregisteredTestsãè¿œå ãããè¿œå ãããã¹ãããŸã£ãã瀺ããŠããªãããšã«æ³šæããŠãã ããã RegisteredTestsã¯ãã©ãŒã ã«æ¥ç¶ããããã°ããŒãã«ãªãTestFrameWorkã¡ãœããã§ãããã°ããŒãã«å€æ°__TestRegistryïŒITestSuite;ãè¿ããŸãã
TestCaseããã®å€æ°ã«ã©ã®ããã«ãé¥ãããã«ã€ããŠã¯ãç¹ã«DUnitã®äœæè
ãäœæ¥ãè¡ã£ãããããã®èšäºã®ç¯å²ããé€å€ããŸãã ãã ããèªè
ããã®ãããã¯ã«é¢å¿ã瀺ããŠããå Žåã¯ãã³ã¡ã³ãã§åçããŸãã ã ãããããªãŒã«æ»ããŸãã ããªãŒãåæåããæ¹æ³ïŒ
procedure TfmGUITestRunner.InitTree; begin FTests.Clear; FillTestTree(Suite); TestTree.ExpandAll; end;
FTestsãããã¯ãã¹ãã®ãªã¹ããä¿åããã€ã³ã¿ãŒãã§ã€ã¹ãªããžã§ã¯ãã®ãªã¹ãã§ãã 次ã«ãFillTestTreeã¡ãœããããªãŒããŒããŒããããŸããããã¯ãããªãŒã®ã«ãŒãèŠçŽ ãšéåžžã®ããŒãã®ã©ã¡ãã§äœæ¥ããŠãããããããªããããè¡ãããŸãã
... procedure FillTestTree(aTest: ITest); overload; procedure FillTestTree(aRootNode: TTreeViewItem; aTest: ITest); overload; ... procedure TfmGUITestRunner.FillTestTree(aRootNode: TTreeViewItem; aTest: ITest); var l_TestTests: IInterfaceList; l_Index: Integer; l_TreeViewItem: TTreeViewItem; begin if aTest = nil then Exit; l_TreeViewItem := TTreeViewItem.Create(self); l_TreeViewItem.IsChecked := True;
ã芧ã®ãšããããã®ã¡ãœããã§ã¯ãããªãŒãåããã ãã§ãªããåããŒãã«å¯Ÿå¿ãããã¹ãã®æ
å ±ãæäŸããŸããã ããŒãããšã«ãã¹ããååŸããã«ã¯ãNodeToTestã¡ãœãããèšè¿°ããŸãã
function TfmGUITestRunner.NodeToTest(aNode: TTreeViewItem): ITest; var l_Index: Integer; begin assert(aNode.Tag >= 0); l_Index := aNode.Tag; Result := FTests[l_Index] as ITest; end;
次ã«ããã¹ãã«ãç¥èããè¿œå ããŸãã åãã¹ãã«ã¯ãTObjectãªã©ã®GUIObjectå€æ°ããããŸãã FormShowã§SetupGUINodesãåŒã³åºããŸãã
procedure TfmGUITestRunner.SetupGUINodes(aNode: TTreeViewItem); var l_Test: ITest; l_Index: Integer; begin for l_Index := 0 to Pred(aNode.Count) do begin
ãã¹ãããããŒããååŸããããã«ãã¡ãœãããèšè¿°ããŸãïŒ
function TfmGUITestRunner.TestToNode(test: ITest): TTreeViewItem; begin assert(assigned(test)); Result := test.GUIObject as TTreeViewItem; assert(assigned(Result)); end;
ç§ããã¹ããããªãŒã«ãæ¥ç¶ãããæ¹æ³ã¯ãç§ãšã·ãã¢ååã奜ãŸãªãã£ãã ãªãDUnitéçºè
ããã®ããã«é²ãã ã®ããšæããŸãã DUnitã¯é·ãéæžãããŠããŸãããããžã§ããªãã¯ã¯ãããŸããã§ããã å°æ¥çã«ã¯ãããã確å®ã«ããçŽããŸãã èšäºã®æåŸã«ã次ã®æ¹åç¹ãšãŠã£ãã·ã¥ãªã¹ãã«ã€ããŠæžããŸãã
ã ãã-ç§ãã¡ã®ããªãŒã¯å»ºèšäžããã¹ãã¯FTestsã«ãããŸãã ãã¹ããšããªãŒã¯çžäºæ¥ç¶ãããŠããŸãã ãã¹ããå®è¡ããçµæãåŠçããŸãã ãã©ãŒã ã§ãããè¡ãã«ã¯ãTestFrameWorkã§èª¬æãããŠããITestListenerã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£
ãè¿œå ããŸãã
ITestListener = interface(IStatusListener) ['{114185BC-B36B-4C68-BDAB-273DBD450F72}'] procedure TestingStarts; procedure StartTest(test: ITest); procedure AddSuccess(test: ITest); procedure AddError(error: TTestFailure); procedure AddFailure(Failure: TTestFailure); procedure EndTest(test: ITest); procedure TestingEnds(testResult :TTestResult); function ShouldRunTest(test :ITest):Boolean; end;
ãããã®ã¡ãœãããã¯ã©ã¹ã®èª¬æã«è¿œå ããŠå®è£
ããŸãã
procedure TfmGUITestRunner.TestingStarts; begin FTotalTime := 0; end; procedure TfmGUITestRunner.StartTest(aTest: ITest); var l_Node: TTreeViewItem; begin assert(assigned(TestResult)); assert(assigned(aTest)); l_Node := TestToNode(aTest); assert(assigned(l_Node)); end; procedure TfmGUITestRunner.AddSuccess(aTest: ITest); begin assert(assigned(aTest)); SetTreeNodeFont(TestToNode(aTest), c_ColorOk) end; procedure TfmGUITestRunner.AddError(aFailure: TTestFailure); var l_ListViewItem: TListViewItem; begin SetTreeNodeFont(TestToNode(aFailure.failedTest), c_ColorError); l_ListViewItem := AddFailureNode(aFailure); end; procedure TfmGUITestRunner.AddFailure(aFailure: TTestFailure); var l_ListViewItem: TListViewItem; begin SetTreeNodeFont(TestToNode(aFailure.failedTest), c_ColorFailure); l_ListViewItem := AddFailureNode(aFailure); end; procedure TfmGUITestRunner.EndTest(test: ITest); begin
説æããç¹å¥ãªãã®ã¯ãããŸããã 質åãããã°ã詳现ã«çããŸãã å
ã®DUnitRunnerã§ã¯ããã¹ãçµæããåãåãããšãã«ã察å¿ããããªãŒããŒãã®ç»åãå€æŽããŸããã ããã«åçã䜿çšã§ããããã«ãªã£ããããåçãã ãŸããŠã¯ãããªãããšã«ããŸãããããŒãã«åçãè¿œå ããããšã¯ãã©ãããã¹ã¿ã€ã«ãéããŠå°ç¡ãã«ãªããŸãã ãããã£ãŠãç§ã¯åããŒãã®FontColorãšFontStyleã®å€æŽã®ã¿ã«å¶éããããšã«ããŸããã
1åéã®ããžãã¹ã®ããã«æããŸããããã¹ãŠã®ããã¥ã¡ã³ããæ°æéæãäžããŸããã
procedure TfmGUITestRunner.SetTreeNodeFont(aNode: TTreeViewItem; aColor: TAlphaColor); begin
ListViewã䜿çšããŠçµæã衚瀺ããŸãã FireMonkeyã®TListViewã®æ©èœã¯ããªã¹ããã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³çšã«å®å
šã«èª¿æŽããããããªãã®ã§ãã ãããŠçŽ æŽãããColumnsããããã£ã倱ããŸããã ãšã©ãŒãè¿œå ããã«ã¯ãAddFailureNodeã¡ãœãããè¿œå ããŸãã
function TfmGUITestRunner.AddFailureNode(aFailure: TTestFailure): TListViewItem; var l_Item: TListViewItem; l_Node: TTreeViewItem; begin assert(assigned(aFailure)); l_Item := lvFailureListView.Items.Add; l_Item.Text := aFailure.failedTest.Name + '; ' + aFailure.thrownExceptionName + '; ' + aFailure.thrownExceptionMessage + '; ' + aFailure.LocationInfo + '; ' + aFailure.AddressInfo + '; ' + aFailure.StackTrace; l_Node := TestToNode(aFailure.failedTest); while l_Node <> nil do begin l_Node.Expand; l_Node := l_Node.ParentItem; end; Result := l_Item; end;
ãã¿ã³ãšèµ·åã¡ãœãããè¿œå ãããã¹ããå®è¡ããŸãã
procedure TfmGUITestRunner.btRunAllTestClick(Sender: TObject); begin if Suite = nil then Exit; ClearResult; RunTheTest(Suite); end; procedure TfmGUITestRunner.RunTheTest(aTest: ITest); begin TestResult := TTestResult.Create; try TestResult.addListener(self); aTest.run(TestResult); finally FreeAndNil(FTestResult); end; end;
ã©ã³ããŒãèµ·åãããã¹ãå®è¡ãã¿ã³ãã¯ãªãã¯ãããšãçµæã衚瀺ãããŸãïŒ
æåŸã«ãããŒãã®ç¶æ
ãå€åãããšãã«ãŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ãåŠçããŸãã
procedure TfmGUITestRunner.TestTreeChangeCheck(Sender: TObject); begin SetNodeEnabled(Sender as TTreeViewItem, (Sender as TTreeViewItem).IsChecked); end; procedure TfmGUITestRunner.SetNodeEnabled(aNode: TTreeViewItem; aValue: Boolean); var l_Test: ITest; begin l_Test := NodeToTest(aNode); if l_Test <> nil then l_Test.Enabled := aValue; end;
äžéšã®ããŒãã®ãã§ãã¯ããã¯ã¹ã®ç¶æ
ãå€æŽããŸãã
å®éã«ãã¹ããããã¹ãã³ãŒãïŒ
unit u_SecondTest; interface uses TestFrameWork; type TSecondTest = class(TTestCase) published procedure DoIt; procedure OtherDoIt; procedure ErrorTest; procedure SecondErrorTest; end;
èŠçŽãããšããã®æ®µéã§ã䜿ãæ
£ããGUIRunnerã䜿çšããŠFireMonkeyã³ãŒãããã¹ãããããã®éåžžã«æ©èœããã¢ããªã±ãŒã·ã§ã³ãã§ããŸããã ãããžã§ã¯ãã¯éããŠããããã誰ã§ã䜿çšã§ããŸãã
ä»åŸã®èšç»ïŒ
lambdaãåãåãããªãŒãã©ããŒãµã«ã¡ãœãããèšè¿°ããŸãã ããªãŒã¯åžžã«ãã€ãã¹ããå¿
èŠããããŸãããåãã©ã³ãã§ã®ã¢ã¯ã·ã§ã³ã¯ç°ãªããããã©ã ãã¯ç§ã«ãšã£ãŠé©åãªããã§ãã
å
茩ããã®ã³ã¡ã³ããšææ¡ïŒ
TDictionary <TTreeViewItemãITest>
docwiki.embarcadero.com/Libraries/XE7/en/System.Generics.Collections.TDictionaryã§ãã¹ãããŒãã®é¢é£ä»ããããçŽã
ãŸããããã¹ãã«åæ Œãã®ã°ã©ãã£ã«ã«ã€ã³ãžã±ãŒã¿ãè¿œå ããŸãã ãã¿ã³-ãã¹ãŠéžæããã¹ãŠåé€ãªã© ãã¹ãçµæã®çµè«ïŒãªãŒãã¿ã€ã ãæåããã³å€±æã®æ°ãªã©ïŒã
ãæŸèæãGUIObjectãåãé€ãããã«ã
ãã³ã¬ãŒã¿ãã¿ãŒã³ãè¿œå ããŸãã
è¿ãå°æ¥ãã¡ã€ã³ãããžã§ã¯ãã§ããMindStreamã®ãã¹ããéå§ããRunnerãå°ãæãèµ·ããããŸãã æåŸãŸã§èªãã§ãããã¿ããªã«æè¬ããŸãã ã³ã¡ã³ããšæ¹è©ããã€ãã³ã¡ã³ãã§æè¿ããŸãã
ãªããžããªãžã®ãªã³ã¯ãpsãããžã§ã¯ãã¯MindStream \ FMX.DUnitãªããžããªã«ãããŸã
ç§ãèŠã€ããããããŠãã®éçšã§ç§ã«ãšã£ãŠæçšã ã£ããªã³ã¯ïŒ
sourceforge.net/p/radstudiodemos/code/HEAD/tree/branches/RadStudio_XE5_Update/FireMonkey/Delphifire-monkey.ru18delphi.blogspot.ruwww.gunsmoker.ruããã·ã¢èªãã§ã®GUIãã¹ãã ãã¹ãã¬ãã«ããŒãããäžåºŠããã¹ãã¬ãã«ãã«ã€ããŠãããŠãã¡ãã
docwiki.embarcadero.com/RADStudio/XE7/en/Main_PageããŒã3.1