Вопрос по unit-testing, frameworks – Каковы лучшие практики в отношении модульного тестирования библиотеки / фреймворка?

3
ContextI»

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

Вопрос

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

Например, базовый тест касается "создание артефакта ", И еще один с "удаление артефакта ", Но, поскольку предполагается, что модульное тестирование является автономным и восстанавливает состояние мира после его завершения, оба эти теста кажутся в какой-то степени связанными: при тестировании создания артефакта нам необходимо очистить состояние в конце теста, фактически удаляя его Это означает, что удаление артефакта само по себе неявно проверяется. То же самое относится и к тестированию удаления артефактов: чтобы настроить мир таким образом, чтобы удаление артефакта было тестируемым, нам нужно сначала создать новый артефакт.

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

Что я'Я склоняюсь к выполнению набора связанных модульных тестов в последовательности, так что каждый модульный тест является дискретным (то есть только тестирует только одну вещь и только одну вещь), но зависит от предыдущих тестов в последовательности для постепенной настройки мира. Тогда моя последовательность может выглядеть так:

[создать артефакт] ->[создать подчиненный артефакт] ->[удалить субартефакт] ->[удалить артефакт]

По этому принципу вся библиотека / фреймворк подвергается модульному тестированию, и состояние мира восстанавливается в конце всего запуска набора тестов. Однако это означает, что любой сбой в середине набора тестов "разбивает мир ".

Каковы некоторые передовые практики и рекомендации, которые могут быть полезны для примирения этих конфликтующих потребностей?

Рекомендации

Что делает хороший модульный тест?

Разве это плохо, когда юнит-тест вызывает другие юнит-тесты?

Ваш Ответ

6   ответов
0

http://xunitpatterns.com/). Это хорошо освещает тему.

1

в котором выполняются тесты (или даже если другие тесты выполняются вообще), не должен иметь значения.

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

Если ваша библиотека отслеживает состояние, у вас могут возникнуть другие проблемы (например, безопасность потоков).

1

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

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

Если у вас есть такие, то в зависимости от:

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

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

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

Качества, которые делают хорошие юнит-тесты, не только не применимы, но и могут быть вредными.

-1. Это'Верно, что интеграционные тесты являются ценными, и что 100% покрытие кода редко того стоит. Это'Также верно, что ограничение тестирования публичными интерфейсами ваших классов является хорошей практикой. Но предполагать, что классы модульного тестирования в отдельности могут быть активно вредными, просто неправильно. Я верю этому'СемьБольше важно следовать рекомендациям по проектированию и тестированию с помощью фреймворка. И я думаю, что вы имели в виду Кент Бек. TrueWill
Лучшая практика для выполнения одной вещи вряд ли будет лучшей практикой для выполнения другой вещи. soru
Мне на самом деле нравится этот ответ лучше, чем другие. Хотя я понимаю лучшие практики, которые уже были объяснены в других местах, большинство других ответов лишь повторяют их, не обращая внимания на фактический контекст оригинального вопроса. Maxime Labelle
2

восстановить состояние мира " Вы имеете в виду очистить базу данных, возможно, или что-то подобное?

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

Так что это оставляет вас с вашими другими тестами, которые звучат немного больше какчерный ящик" тесты или интеграционные тесты, или как вы хотите их называть. Они полагаются на внешнее состояние, которое необходимо настроить, контролировать, разрушать и т. Д.

Вы должны определенно ожидать, что они будут более хрупкими, чем юнит-тесты.

Мое личное мнение таково, что как только вы пройдете эти тесты ... это действительно зависит. Что ты'предлагает неЗвучит необоснованно.

Я склонен создавать сильный набор изолированных модульных тестов и полагаюсь на тесты, которые выописано для финалатестирование клея », Поэтому они'не слишком подробно и неПопробуйте и попробуйте все аспекты библиотеки.

0

Сделайте тесты независимыми, чтобы их можно было запускать отдельно и в любой последовательности.Начните каждый тест в известном, чистом состоянии.Создайте окружающую среду, используя светильники. Снова посмотрите на db: unit. Мне нравится хорошоканонический» состояние базы данных и восстанавливать ее перед каждым тестом (или откатывать).

Я не согласен с одним из ваших предположений: тест должен ВОССТАНОВИТЬ свое состояние до завершения. Вы также можете сказать этоs ответственность за выполнение этого теста; инструменты типа db: unit делают это. Они позволяют вам писать свои тесты более свободно.

Ваш последовательный тест имеет смысл, но на практике он становится сложным. (Я'пробовал) Как вы уже упоминали, вы неполучить хорошие отчеты о сбоях. Кроме того, поскольку программа выходит за рамки 4 тестов, выНужно выяснить, где в последовательности вставить тест, чтобы данные как раз подходили для него. Это быстро станет слишком сложно рассуждать. (Вспомните 100 или 1000 тестов). Тот'Почему тестовые установки (или фабрики) имеют смысл.

Кент Бекs Test Driven Development: By Example подробно обсуждает эту тему.

0

на каком языке вы программируете. В Java вы можете создавать TestSuites с помощью API JUnit. Вы добавляете отдельные тесты в TestSuite и запускаете TestSuite в целом.

Похожие вопросы