как сделать элегантный модульный тест на операторе графика - PullRequest
0 голосов
/ 28 мая 2020

У меня есть приложение для вычисления графов. Я хочу, чтобы на него был включен тестовый модуль, но я обнаружил, что это сложно выполнить.

Основной класс показан следующим образом:

  • Grid store структура графа

  • GridInput проанализируйте входной файл и сохраните его в Grid.

  • GridOperatorA выполните некоторые операции с Grid.

  • GridOperatorB выполните некоторые операции с Grid.

производственный код выглядит как

string configure_file = "data.txt";
GridInput input(configure_file);
Grid grid = input.parseGrid();
GridOperatorA a;
a.operator(grid);
GridOpeartorB b;
b.operator(grid);

Я обнаружил, что код трудно проверить.

Мой код модульного теста показан следующим образом

// unit test for grid input
string configure_file = "data.txt";
GridInput input(configure_file);
Grid grid = input.parseGrid();
// check grid status from input file
assert(grid.someAttribute(1) == {1,2,3,4,...,100}); // long int array hard to understand
...
assert(grid.someAttribute(5) == {100,101,102,...,200}); // long int array hard to understand
// unit test for operator A
string configure_file = "data.txt";
GridInput input(configure_file);
Grid grid = input.parseGrid();
GridOperatorA a;
a.operator(grid);
// check grid status after opeator A
assert(grid.someAttribute(1) == {1,3,,7,4,...,46}); // long int array hard to understand
...
assert(grid.someAttribute(5) == {59,78,...,32}); // long int array hard to understand
// unit test for operator B
string configure_file = "data.txt";
GridInput input(configure_file);
Grid grid = input.parseGrid();
GridOperatorA a;
a.operator(grid);
GridOperatorA b;
b.operator(grid);
// check grid status after opeator B
assert(grid.someAttribute(1) == {3,2,7,9,...,23}); // long int array hard to understand
...
assert(grid.someAttribute(5) == {38,76,...,13}); // long int array hard to understand

В моем варианте мой модульный тест не подходит, он иметь много отсталости

  • модульный тест выполняется медленно, чтобы протестировать OperatorA, OperatorB, необходимо выполнить файл IO

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

  • юнит-тест предназначен только для одного файла конфигурации, если мне нужно протестировать сетку из нескольких файлов конфигурации, будет даже более сложный для понимания массив.

Я прочитал некоторые методы, позволяющие разорвать зависимости, например, фиктивный объект. Я могу издеваться над grid, прочитанным из файла конфигурации. Но фиктивные данные похожи на хранилище данных в файле конфигурации. Я могу издеваться над Grid после operatorA, но фиктивные данные точно такие же, как статус сетки после operatorA. Они также приведут к созданию большого количества массивов, которые трудно понять.

Я не знаю, как выполнить элегантный модульный тест в моей ситуации. Любой голос ценен. Спасибо за ваше время.

1 Ответ

1 голос
/ 28 мая 2020

Чтобы избавиться от io

  • , вы можете передать что-то вроде поставщика данных в GridInput. В вашем производственном коде он будет читать файл. В тестовом коде вы можете заменить его тестовым двойником (заглушкой), который предоставляет жестко закодированные данные. Вы уже упоминали об этом выше.

  • вы также можете позволить «кому-то другому» (т.е. другому коду) позаботиться о загрузке файла и просто передать загруженные данные в сетку. Просто глядя на сетку, тестирование становится проще, потому что обработка файлов не требуется.

Чтобы сделать тест более читабельным, вы можете сделать следующее:

  • используйте красивые имена тестовых методов, а не просто testMethod. Назовите их в честь того, что вы тестируете. Вы можете использовать свои комментарии как имена методов. Проверьте только один аспект в одном тесте.

  • замените встроенный массив константами с правильными именами. Имя констант может помочь понять, что проверяется в данном утверждении.

  • То же самое относится и к параметрам метода someAttribute().

  • Другой вариант - создать собственные методы утверждения, чтобы скрыть некоторые детали. Что-то вроде assertThatMySpecialConditionIsMet(grid).

Вы также можете написать генератор тестовых данных, чтобы избежать жесткого кодирования массивов. Не то, что я бы предложил для первого теста. После пары тестов становится видимым образец, который можно переместить в генератор.

Всего пара подсказок для начала ....: -)

...