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 ...


Комментариев нет:
Отправить комментарий