Часть 2 .
Часть 3 .
Закончил сегодня быстрый о том, как мы решили написать свой GUIrunner для FireMonkey. В комментарии к посту в одной из социальных сетей Алексей Тимохин обратил мое внимание на еще один известный фреймворк для тестирования — DUnitX. Я пытался найти альтернативу, использовать консольный вариант, но Александр был неумолим.
Когда я зашёл в репозиторий и увидел готовый GUIrunner для FireMonkey, то совсем упал.
Однако.
После первого запуска мое первое сообщение Александру было: «лол.
Никаких флажков нет».
Значит проблема решена не зря.
При более внимательном рассмотрении выяснилось, что человек, написавший эту форму, тоже немного присматривался к Original GUIrunner. В общем, я был бы очень рад такому подарку еще месяц назад, когда FireMonkey был еще в зачаточном состоянии.
Что ж, сегодня мне просто интересно, как другой программист решил ту же проблему.
Мы допустили ряд почти одинаковых ошибок.
В посте я написал о том, как мы «связываем» тесты и ветки и закончил предложением по рефакторингу с помощью TDictionary. Напомню, как в оригинале:
Разработчик DUnitX сделал нечто подобное, однако сделал обертку над TTreeViewItem (в будущем добавлю к себе):l_Test.GUIObject := aNode.Items[l_Index]; .
l_TreeViewItem.Tag := FTests.Add(aTest);
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>;
Угадайте, зачем нам нужен строковый ключ? Правильно использовать его, чтобы добраться до филиала и сообщить о его состоянии после результата теста.
На мой взгляд, они были слишком умны.
Отдельного упоминания заслуживает класс 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 .
Теги: #delphi #FireMonkey #firemonkey mobile #firemonkey mobile #tdd #delphi #дизайн и рефакторинг #tdd
-
Бухгалтерские Программы
19 Oct, 24 -
И Снова Зип-Квест
19 Oct, 24