Original in Russian: http://18delphi.blogspot.ru/2013/11/gui-dunit.html
GUI-testing. Table of contents
Now, let us make one thing – add DUnit to our scripts.
First, let’s make test VCL-project in analogy to FM-project.
It is more than simple:
The code of the project:
The code of the main form:
ALL THE REST project files HAVE NOT CHANGED.
The publication of scripts in DUnit is MORE that SIMPLE:
The code of “test suite”:
Here the code for l_FileName in TDirectory.GetFiles – flips through the files in the directory by mask.
My gratitude to Roman Yankovsky (http://roman.yankovsky.me/) for a hint (http://programmingmindstream.blogspot.ru/2013/12/blog-post_16.html?showComment=1387279738393#c6313390821290709952).
And the type of a SEPARATE script test:
What is it all about?
OBVIOUSLY – we flip through the files by mask *.script in the directory of EXE-file and create a SEPARATE DUnit-test for EACH file of this kind.
We launch our project and see two forms:
The main form of the application:
And the form with the list of tests:
And one more remark. Of course, in a SIMILAR WAY you can “multiply” tests on EVERY iterator parameter, not just on script file.
Later I’m planning to write how tests can be “multiplied” on input/output.
This is something like in library I’ve been referred to by Roman Yankovsky, where tests multiply on their own attributes. Here - http://18delphi.blogspot.ru/2013/04/blog-post_7108.html . - the references about it are collected.
In the “script axiomatics” one ASSUMPTION is made.
Right here:
- as an “active” form ANY form that DIFFERS from DUnit-form (TGUITestRunner) is regarded. Of course, this is just an “example”.
In the REAL LIFE it is “easily fixed”.
FOR NOW Draft of the project is here - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/GUITests/Chapter3/
It is interesting? Should I write on this theme this weekend?
Or should I write about the “face” for FM-projects for DUnit?
... to be continued ...
GUI-testing. Table of contents
Now, let us make one thing – add DUnit to our scripts.
First, let’s make test VCL-project in analogy to FM-project.
It is more than simple:
The code of the project:
program VCLProject; uses Vcl.Forms, Script.Engine in 'Scripting\Script.Engine.pas', Script.Parser in 'Scripting\Script.Parser.pas', Script.Interfaces in 'Scripting\Script.Interfaces.pas', Core.Obj in 'Core\Core.Obj.pas', Testing.Engine in 'Testing\Testing.Engine.pas', Script.WordsInterfaces in 'Scripting\Script.WordsInterfaces.pas', Script.Code in 'Scripting\Script.Code.pas', Script.Dictionary in 'Scripting\Script.Dictionary.pas', Script.Word in 'Scripting\Script.Word.pas', Script.StringWord in 'Scripting\Script.StringWord.pas', Script.UnknownToken in 'Scripting\Script.UnknownToken.pas', Script.Axiomatics in 'Scripting\Script.Axiomatics.pas', Script.Word.Examples in 'Scripting\Script.Word.Examples.pas', Script.Word.Buttons in 'Scripting\Script.Word.Buttons.pas', VCLForm1 in 'VCLForm1.pas' {Form1}, GUITestRunner, DUnit.Scripting.AutoTests in 'DUnitScripting\DUnit.Scripting.AutoTests.pas', DUnit.Scripting.AutoTest in 'DUnitScripting\DUnit.Scripting.AutoTest.pas'; {$R *.res} begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); // GUITestRunner.RunRegisteredTests; GUITestRunner.RunRegisteredTestsModeless; Application.Run; end.
The code of the main form:
unit VCLForm1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Script.Interfaces ; type TForm1 = class(TForm, IscriptCompileLog, IscriptRunLog) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; CompileLog: TMemo; RunLog: TMemo; Run: TButton; procedure Button1Click(Sender: TObject); procedure RunClick(Sender: TObject); private { Private declarations } procedure IscriptCompileLog_Log(const aString: String); procedure IscriptCompileLog.Log = IscriptCompileLog_Log; procedure IscriptRunLog_Log(const aString: String); procedure IscriptRunLog.Log = IscriptRunLog_Log; public { Public declarations } end; var Form1: TForm1; implementation uses Testing.Engine, Script.Engine ; {$R *.dfm} procedure TForm1.IscriptCompileLog_Log(const aString: String); begin CompileLog.Lines.Add(aString); {$IfNDef NoTesting} TtestEngine.CurrentTest.SocketMetric(TtestSocket.Create(Self, 'IscriptCompileLog_Log')).PutValue(aString); {$EndIf NoTesting} end; procedure TForm1.IscriptRunLog_Log(const aString: String); begin RunLog.Lines.Add(aString); {$IfNDef NoTesting} TtestEngine.CurrentTest.SocketMetric(TtestSocket.Create(Self, 'IscriptRunLog_Log')).PutValue(aString); {$EndIf NoTesting} end; procedure TForm1.Button1Click(Sender: TObject); begin Edit1.Text := (Sender As TButton).Caption + ' clicked'; end; procedure TForm1.RunClick(Sender: TObject); const l_FileName = 'FirstScript.script'; begin CompileLog.Lines.Clear; RunLog.Lines.Clear; {$IfNDef NoTesting} TtestEngine.StartTest(l_FileName); try {$EndIf NoTesting} TScriptEngine.RunScript(l_FileName, Self, Self); {$IfNDef NoTesting} finally TtestEngine.StopTest; end;//try..finally {$EndIf NoTesting} end; end.
ALL THE REST project files HAVE NOT CHANGED.
The publication of scripts in DUnit is MORE that SIMPLE:
The code of “test suite”:
unit DUnit.Scripting.AutoTests; interface uses TestFrameWork, Core.Obj ; type TautoTests = class(TTestSuite) public procedure AddTests(testClass: TTestCaseClass); override; end;//TautoTests implementation uses DUnit.Scripting.AutoTest, System.IOUtils, System.SysUtils, Testing.Engine ; procedure TautoTests.AddTests(testClass: TTestCaseClass); var l_FileName : String; begin Assert(testClass.InheritsFrom(TautoTest)); {$IfNDef NoTesting} TtestEngine.StartTest('Initialization'); try {$EndIf NoTesting} for l_FileName in TDirectory.GetFiles(ExtractFilePath(ParamStr(0)), '*.script') do begin {$IfNDef NoTesting} TtestEngine.CurrentTest.SocketMetric(TtestSocket.Create(Self, 'AddTests')).PutValue(l_FileName); {$EndIf NoTesting} AddTest(RautoTest(testClass).Create(l_FileName)); // TScriptEngine.RunScript(l_FileName, Self, Self); end;//for l_FileName in TDirectory {$IfNDef NoTesting} finally TtestEngine.StopTest; end;//try..finally {$EndIf NoTesting} //inherited; end; initialization TestFramework.RegisterTest(TautoTests.Create(TautoTest)); end.
Here the code for l_FileName in TDirectory.GetFiles – flips through the files in the directory by mask.
My gratitude to Roman Yankovsky (http://roman.yankovsky.me/) for a hint (http://programmingmindstream.blogspot.ru/2013/12/blog-post_16.html?showComment=1387279738393#c6313390821290709952).
And the type of a SEPARATE script test:
unit DUnit.Scripting.AutoTest; interface uses TestFrameWork ; type TautoTest = class(TTestCase) public constructor Create(MethodName: string); override; protected procedure DoIt; end;//TautoTest RautoTest = class of TautoTest; implementation uses Script.Engine, Testing.Engine ; constructor TautoTest.Create(MethodName: string); begin inherited Create(MethodName); FMethod := DoIt; end; procedure TautoTest.DoIt; begin {$IfNDef NoTesting} TtestEngine.StartTest(FTestName); try {$EndIf NoTesting} TScriptEngine.RunScript(FTestName, nil, nil); {$IfNDef NoTesting} finally TtestEngine.StopTest; end;//try..finally {$EndIf NoTesting} // TScriptEngine.RunScript(FTestName, nil, nil); end; end.
What is it all about?
OBVIOUSLY – we flip through the files by mask *.script in the directory of EXE-file and create a SEPARATE DUnit-test for EACH file of this kind.
We launch our project and see two forms:
The main form of the application:
And the form with the list of tests:
And one more remark. Of course, in a SIMILAR WAY you can “multiply” tests on EVERY iterator parameter, not just on script file.
Later I’m planning to write how tests can be “multiplied” on input/output.
This is something like in library I’ve been referred to by Roman Yankovsky, where tests multiply on their own attributes. Here - http://18delphi.blogspot.ru/2013/04/blog-post_7108.html . - the references about it are collected.
In the “script axiomatics” one ASSUMPTION is made.
Right here:
procedure TkwFindComponent.DoDoIt(aContext: TscriptContext); var l_Name : String; l_Component : TComponent; l_ActiveForm : TForm; l_Index : Integer; begin l_Name := aContext.PopString; Assert(l_Name <> ''); l_ActiveForm := nil; for l_Index := 0 to Pred(Screen.FormCount) do if (Screen.Forms[l_Index].ClassName <> 'TGUITestRunner') then begin l_ActiveForm := Screen.Forms[l_Index]; break; end;//Screen.Forms[l_Index].ClassName <> 'TGUITestRunner' Assert(l_ActiveForm <> nil); l_Component := l_ActiveForm.FindComponent(l_Name); Assert(l_Component <> nil); aContext.PushObject(l_Component); end;
- as an “active” form ANY form that DIFFERS from DUnit-form (TGUITestRunner) is regarded. Of course, this is just an “example”.
In the REAL LIFE it is “easily fixed”.
FOR NOW Draft of the project is here - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/GUITests/Chapter3/
It is interesting? Should I write on this theme this weekend?
Or should I write about the “face” for FM-projects for DUnit?
... to be continued ...
Комментариев нет:
Отправить комментарий