Original in Russian: http://18delphi.blogspot.ru/2013/11/gui.html
GUI-testing. Table of contents
About the real implementation it is written here:
http://18delphi.blogspot.ru/2013/10/blog-post_7652.html
http://18delphi.blogspot.ru/2013/10/blog-post_7099.html .
Now, I’ll try to describe the concept.
Let us have a form:
TSomeForm = class(TForm) SomeButton : TButton; end;//TSomeForm
Suppose we want to have a possibility to press button SomeButton on form SomeForm.
From our tests.
To do this, we can use the following test engine words:
interface TkwFindForm = class(TscriptKeyWord) protected procedure DoIt(aContext : TscriptContext); override; end;//TkwFindForm TkwFindComponent = class(TscriptKeyWord) protected procedure DoIt(aContext : TscriptContext); override; end;//TkwFindComponent TkwButtonClick = class(TscriptKeyWord) protected procedure DoIt(aContext : TscriptContext); override; end;//TkwButtonClick
The implementation:
implementation procedure TkwFindForm.DoIt(aContext : TscriptContext); var l_Name : String; l_Form : TForm; begin l_Name := aContext.PopString; Assert(l_Name <> ''); l_Form := Screen.FindFormByName(l_Name); // - this method does not exist, but it can easily be written Assert(l_Form <> nil); aContext.PushObject(l_Form); end; procedure TkwFindComponent.DoIt(aContext : TscriptContext); var l_Name : String; l_Form : TForm; l_Component : TComponent; begin l_Name := aContext.PopString; l_Form := aContext.PopObject As TForm; Assert(l_Name <> ''); Assert(l_Form <> nil); l_Component := l_Form.FindComponent(l_Name); Assert(l_Component <> nil); aContext.PushObject(l_Component); end; procedure TkwButtonClick.DoIt(aContext : TscriptContext); var l_Component : TComponent; begin l_Component := aContext.PopObject As TComponent; Assert(l_Component Is TButton); (l_Component As TButton).Click; end;
We register the described words in test engine:
initialization ScriptEngine.RegisterWord(TkwFindForm, 'FindForm'); ScriptEngine.RegisterWord(TkwFindComponent, 'FindComponent'); ScriptEngine.RegisterWord(TkwButtonClick, 'ButtonCick');
It is obvious that words identifiers can be “created” from ClassName, but it is not important.
Now, we can write the first test:
VAR l_Form VAR l_Button 'SomeForm' FindForm =: l_Form l_Form 'SomeButton' FindComponent =: l_Button l_Button ButtonClick
It does want we want from it.
(You shouldn’t be scary of the reverse Polish. I write like this because I’ve got it. Historically. The reverse Polish or infix notation – not a real problem)
But. I would like “in the spoken style”.
We’ll write “auxiliary” words, already on script language of test engine.
Suppose we know that SomeForm is a user registration form, and SomeButton is a button for saving.
It also comes from the business logic.
Let’s write:
CONST "Registration form" 'SomeForm' CONST "Save" 'SomeButton'
Then, we can rewrite the test in this way:
VAR l_Form VAR l_Button " Registration form" FindForm =: l_Form l_Form "Save" FindComponent =: l_Button l_Button ButtonClick
Let’s move on.
We write:
STRING FUNCTION "Find the form" STRING IN aFormName aFormName FindForm =: Result END //" Find the form" STRING FUNCTION "Find find the component on the form" STRING IN aComponentName OBJECT IN aForm aForm aComponentName FindComponent =: Result END //" Find find the component on the form"" PROCEDURE "Press the button" OBJECT IN aButton aButton ButtonClick END //" Press the button" WORDALIAS VAR Variable
Then, the test can be rewritten in this way:
Variable "Found form" Variable " Found button" "Find the form {("Registration form")}" =: "Found form" "Find find the component {("Save")} on the form {("Found form")}" =: "Found button" "Press the button {("Found button")}"
And the finishing touch.
We input the written word to the dictionary:
PROCEDURE "Press the button Save on registration form" Variable "Found form" Variable " Found button" "Find the form {("Registration form")}" =: "Found form" "Find find the component {("Save")} on the form {("Found form")}" =: "Found button" "Press the button {("Found button")}" END //"Press the button Save on registration form"
Now, test looks as follows:
"Press the button Save on registration form "
- all reserved structures – are "hidden" inside “high-level words” – “Press the button Save on registration form”.
It is no longer a “word”, but actually a full “sentence”.
The one that got into script engine dictionary and is taken as valid identifier by the script engine.
The one that starts to take part in scripts compilation process.
Why do we need it?
Of course, not to “write in the spoken style”. This is surely a utopia.
The idea is these tests can be “write and read in any language”.
Test resembles TestCase.
It can be run not only by the script machine, but a human being.
Finally – the “self-documenting” of the code.
Thus, by finding the required “handles” in Delphi (not necessarily through RTTI) and describing the “high-level” words in temporary dictionaries of the test engine – we can quickly “gain weight” we need to write tests of TestCase kind.
A bit about “how this all is organized inside” read here - http://18delphi.blogspot.com/2015/03/gui-testing-10-gui-testing-in-spoken.html
Комментариев нет:
Отправить комментарий