Можно ли копировать и вставлять юнит-тесты, когда логика в основном одинакова?

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

Это ваш словарь

d = {2:3, 1:89, 4:5, 3:0}

Создайте новый словарь d1, отсортировав его d с использованием лямбда-функции

d1 = dict(sorted(d.items(), key = lambda x:x[0]))

d1 должно быть {1: 89, 2: 3, 3: 0, 4: 5}, отсортировано по клавишам в d.

20
задан Rob 26 August 2010 в 20:11
поделиться

8 ответов

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

Суть в том, что дублирование кода - это почти всегда неправильное решение. В данном примере вы могли бы рефакторизовать код проверки в метод под названием, например, IsTetrisPieceUnableToMoveLeftBecauseOfAPieceOrAWall. Я всегда использую такие описательные имена методов, когда пишу немного "общей" функциональности для модульного теста, так как это делает чрезвычайно ясным, что именно делается/тестируется.

30
ответ дан 29 November 2019 в 22:31
поделиться

Тестовый код похож на любой другой код, и его следует поддерживать и подвергать рефакторингу.

Это означает, что если у вас общая логика, извлеките ее в отдельную функцию.

Некоторые библиотеки модульного тестирования, такие как семейство xUnit, имеют специальные тестовые инструменты, атрибуты настройки и удаления для такого общего кода.

См. этот связанный с вопрос - «Почему копирование и вставка кода опасно?».

14
ответ дан 29 November 2019 в 22:31
поделиться

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

Однако это только шаг 1. Шаг 2 - это рефакторинг для обеспечения общности, а шаг 1 предназначен только для того, чтобы помочь вам увидеть эту общность. Если вы уже можете ясно видеть это без копирования (иногда проще сначала скопировать, а затем исследовать, иногда это не так, и это зависит от человека, который это делает), пропустите шаг 1.

8
ответ дан 29 November 2019 в 22:31
поделиться

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

1
ответ дан 29 November 2019 в 22:31
поделиться

Если вы повторяете код, вам необходимо выполнить рефакторинг. Ваша ситуация является распространенной проблемой и решается с помощью «Параметрического тестирования». Параметрическое тестирование при поддержке тестовой оснастки позволяет передавать несколько наборов входных значений в качестве параметров. Вы также можете найти Fuzz testing, я обнаружил, что это полезно в таких ситуациях.

1
ответ дан 29 November 2019 в 22:31
поделиться

Я согласился @Rob. Код нуждается в рефакторинге. Но если вы не хотите проводить рефакторинг кода на данном этапе, вы можете пойти и провести параметризованные тесты. Один и тот же тестовый прогон для разных параметров. См. Атрибуты TestCase и TestCaseSource в nunit.

См. http://nunit.org/index.php?p=parameterizedTests&r=2.5

1
ответ дан 29 November 2019 в 22:31
поделиться

Веб-сайт xunitpatterns.org говорит "нет" (копирование/вставка не подходит), потому что это может увеличить затраты, когда тесты необходимо обновлять:

"Вырезать и вставить" - это мощный инструмент для быстрого написания кода, но он приводит к созданию множества копий одного и того же кода, каждая из которых должна поддерживаться каждая из которых должна поддерживаться параллельно.

и для дальнейшего чтения он также ссылается на статью

By: Arie van Deursen, Leon Moonen, Alex van den Bergh, Gerard Kok

1
ответ дан 29 November 2019 в 22:31
поделиться

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

  • Рабочий код может допускать некоторую сложность, чтобы быть понятным / поддерживаемым. Вы хотите, чтобы код находился на правильном уровне абстракции, а дизайн был согласованным. Это нормально, потому что у вас есть тесты, и вы можете убедиться, что это работает. Дублирование кода в производственном коде не было бы проблемой, если бы у вас действительно было 100% покрытие кода на логическом уровне. Этого действительно трудно достичь, поэтому правило таково: избегайте дублирования и максимально увеличивайте охват кода.

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

Главное, что я хочу сказать, это то, что производственный и тестовый код имеют разную природу. Тогда это всегда вопрос здравого смысла, и я не говорю, что вы не должны множить тестовый код и т. Д. Если вы можете учесть что-то в тестовом коде и уверены, что это нормально, сделайте это.Но для тестового кода я предпочел бы простоту элегантности, а для производственного кода я бы предпочел элегантность простоте. Оптимальным, конечно же, является простое и элегантное решение :)

PS: Если вы действительно не согласны, оставьте, пожалуйста, комментарий.

27
ответ дан 29 November 2019 в 22:31
поделиться