По мотивам GUIRunner

    Часть 1.
    Часть 2.
    Часть 3.

    Сегодня дописал пост о том, как мы решили написать свой GUIRunner для FireMonkey. В комментарии к посту в одной из соцсетей Алексей Тимохин обратил мое внимание на другой известный фреймворк для тестирования — DUnitX.
    Я пытался найти альтернативу, использовать консольный вариант, но Александр был неумолим. Когда же зайдя в репозиторий я увидел готовый GUIRunner под FireMonkey, совсем поник.

    Однако.

    После первого запуска первым моим сообщением Александру было — " lol. Там «галочек» нету." Так что проблему решал не зря. После более внимательного изучения сложилось впечатление, что человек, который писал эту форму, тоже отчасти «поглядывал» в Original GUIRunner.

    В целом я бы очень обрадовался такому подарку с месяц назад, пока шишки FireMonkey ещё не набились. Ну а сегодня мне было просто интересно, как решал эту же задачу другой программист.

    Ряд ошибок мы допустили практически одинаковых. В посте я писал о том, как мы «связываем» тесты и ветки и в конце закончил предложением о рефакторинге с использованием TDictionary. Напомню, как в оригинале:

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

    Разработчик DUnitX поступил примерно также, правда, он сделали обертку над TTreeViewItem (в будущем добавлю к себе):

    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;
    

    И связал каждый тест с веткой по имени теста.

    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;
    

    Удивило меня другое:

      FFailedTests: TDictionary<String, ITestResult>;
    

    Угадайте, зачем нам ключ String? Правильно, чтобы по нему добраться до ветки и сообщить о её состоянии после результата теста. Как по мне, перемудрили.

    Отдельного упоминания заслуживает класс TTreeNode. Он в себе хранит «ссылку» на тест и картинку, которая будет изменять состояние ветки. Так как класс унаследован от TreeViewItem, такой код живет отлично:

    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;  
    

    В целом DUnitX произвёл на меня хорошее впечатление. Фреймворк кажется намного солиднее своего старшего брата. Интерфейсы и архитектуру ребята пересмотрели и, думаю, даже улучшили. Весь код очень аккуратный. Комментариев больше в разы. Буду присматриваться и сравнивать.

    Ссылки


    Репозиторий Delphi-Mocks. Необходим для компилирования фреймворка;
    Репозиторий DUnitX.
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 3
    • 0
      Ничего не понятно.
      Что такое GUIRunner? Чем вам стандартный не угодил, каких «галочек» не хватило? Что не так в первом листинге?
    • +1
      DUnitX как раз не хватает VCL gui. Может кто нибудь сподобится…
      Гуи на самом деле не сильно нужен. Главное проблема, что и в консольном режиме нет возможности выборочного прогона тестов.

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.