Based on GUIRunner

    Part 1 .
    Part 2 .
    Part 3 .

    Today I added a post about how we decided to write our GUIRunner for FireMonkey. In a comment on a post on one of the social networks, Alexey Timokhin drew my attention to another well-known testing framework - DUnitX.
    I tried to find an alternative, use the console option, but Alexander was implacable. When I went into the repository, I saw the finished GUIRunner under FireMonkey, completely wilted.

    However.

    After the first launch, my first message to Alexander was - "lol. There are no" ticks "." So the problem was not solved in vain. After a more careful study, the impression was that the person who wrote this form also partially “glanced” in the Original GUIRunner.

    In general, I would be very happy with such a gift from a month ago, until the FireMonkey cones were still full. Well, today I was just wondering how another programmer solved the same problem.

    We made a number of mistakes almost the same. In a post I wrote about how we “bind” tests and branches, and in the end I ended up with a refactoring proposal using TDictionary. Let me remind you, as in the original:

      l_Test.GUIObject := aNode.Items[l_Index];
      ...
      l_TreeViewItem.Tag := FTests.Add(aTest);
    

    The DUnitX developer did the same, though, he did a wrapper on TTreeViewItem (I’ll add to myself 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;
    

    And associated each test with a branch named 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;
    

    Another thing surprised me:

      FFailedTests: TDictionary;
    

    Guess why we need the String key? It’s correct to get to the branch along it and report on its state after the test result. As for me, they are too smart.

    The TTreeNode class deserves special mention. It stores in itself a “link” to the test and a picture that will change the state of the branch. Since the class is inherited from TreeViewItem, such code lives perfectly:

    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 good impression on me. The framework seems much more solid than his older brother. The guys revised the interfaces and architecture and, I think, even improved them. All code is very neat. More comments at times. I will look closely and compare.

    References


    Repository Delphi-Mocks . Required to compile the framework; DUnitX
    repository .

    Also popular now: