вторник, 13 января 2015 г.

MindStream. How we develop software for FireMonkey. Part 3.1. Inspired by GUIRunner

Original post in Russian: http://habrahabr.ru/post/241377/ 

Table of contents

Inspired by GUIRunner

I’ve finished my post about how we’ve decided to develop our own GUIRunner for FireMonkey. In the commentaries to the post in one of the social networks Aleksey Timohin has drawn my attention to another framework for testing – DUniX.
I have tried to find the alternative by using the console version but Alexander was implacable. When I entered the repository and saw a finished GUIRunner for FireMonkey I quite drooped my head.

Anyway. After running DUniX for the first time I have written to Alexander: “LOL. There are no ticks there”. So I did not solve the problem in vain. After a more thorough examining I had the impression that a person who coded this form has also “peered” a bit into Original GUIRunner.
In general, I would really be pleased with such a gift near a month ago when I have not yet learned through mistakes. And today I was just interested how another programmer solved this problem. We’ve made a number of almost the same mistakes. I have written in the post about how to connect tests with branches and it ended with me offering to perform refactoring using TDictionary.
Let me remind you of the original:
  l_Test.GUIObject := aNode.Items[l_Index];
  ...
  l_TreeViewItem.Tag := FTests.Add(aTest);
DUnitX developer did in almost the same way. However, he made a wrapper on TTreeViewItem (I will adopt it in the future):
type
  TTestNode = class(TTreeViewItem)
  strict private
    FFullName: String;
    FImage: TImage;
  public
    constructor Create(Owner: TComponent; Text: String; TestFullName: String); reintroduce;
    destructor Destroy; override;
    property FullName: String read FFullName;
    procedure SetResultType(resultType: TTestResultType);
    procedure Reload;
  end;
I connected each test with a branch named after the test.
function TGUIXTestRunner.GetNode(FullName: String): TTreeViewItem;
var
  i: Integer;
begin
  Result := nil;
  i := 0;
  repeat begin
    if (TestTree.ItemByGlobalIndex(i) as TTestNode).FullName = FullName then
      Result := TestTree.ItemByGlobalIndex(i);
    Inc(i);
   end
   until Assigned(Result) or (i >= TestTree.GlobalCount);
end;
What surprised me is the following issue:
  FFailedTests: TDictionary<string>;
Try to guess why do we need key String? That’s right – so that with a help of it we could get to the branch and report on its state after having finished the test. As for me, we’ve overcomplicated things. Class TTreeNode is worth special mentioning. It stores a “link” to the test and a picture that will change the state of the branch. Since this class is inherited from TreeViewItem, this code works successfully:
var
   testNode : TTreeViewItem;  
   ...
   testNode := CreateNode(TestTree, test.Name, test.Fixture.FullName + '.' + test.Name);
   ...

function TGUIXTestRunner.CreateNode(Owner: TComponent; Text: String; TestFullName: String): TTreeViewItem;
begin
  Result := TTestNode.Create(Owner, Text, TestFullName);
end;
...
constructor TTestNode.Create(Owner: TComponent; Text, TestFullName: String);
begin
  inherited Create(Owner);
  Self.Text := Text;
  FFullName := TestFullName;
  FImage := TImage.Create(Owner);
  FImage.Parent := Self;
  {$IFDEF DELPHI_XE6_UP}
  FImage.Align := TAlignLayout.Right;
  {$ELSE}
  FImage.Align := TAlignLayout.alRight;
  {$ENDIF}
  FImage.Bitmap.Create(15, 15);
  FImage.Bitmap.Clear(TAlphaColorRec.Gray);
  FImage.SendToBack;
end;  
In general, DUnitX made a positive impression on me. The framework seems to be far more trust-worthy than its “big brother”. The developers reconsidered and in a way improwed the interface and the architecture. The whole code looks really neat. There are much more commentaries there. I will examine and compare.
Links:
Repository Delphi-Mocks. Need for compile the framework.
Repository DUnitX.

Комментариев нет:

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