Рекомендации По модульному тестированию

StackOverflow https://stackoverflow.com/questions/106800

  •  01-07-2019
  •  | 
  •  

Вопрос

Кто-нибудь знает, где найти руководства по модульному тестированию и рекомендации?Я хотел бы иметь что-то, что затрагивает следующие типы тем (например):

  • Должны ли тесты быть в том же проекте, что и логика приложения?
  • Должен ли я иметь тестовые классы, отражающие мои логические классы, или у меня должно быть только столько тестовых классов, сколько я считаю нужным?
  • Как я должен называть свои тестовые классы, методы и проекты (если они входят в разные проекты)
  • Должны ли тестироваться частные, защищенные и внутренние методы или только те, которые являются общедоступными?
  • Следует ли разделять модульные и интеграционные тесты?
  • Есть ли какой-нибудь хорошо причина не иметь 100% тестового покрытия?

О чем я не спрашиваю, чем я должен быть?

Лучше всего было бы использовать онлайн-ресурс.

Это было полезно?

Решение

Я бы порекомендовал Кент Бек книга о TDD.

Кроме того, вам нужно перейти к У Мартина Фаулера Сайт.У него также есть много полезной информации о тестировании.

Мы довольно хорошо разбираемся в TDD, поэтому я отвечу на вопросы в этом свете.

Должны ли тесты быть в том же проекте, что и логика приложения?

Обычно мы сохраняем наши тесты в одном и том же решении, но мы разбиваем тесты на отдельные библиотеки DLL / проекты, которые отражают библиотеки DLL / проекты, которые они тестируют, но поддерживаем пространства имен, в которых тесты находятся во вложенном пространстве имен.Пример:Общий / Common.Тесты

Должен ли я иметь тестовые классы, отражающие мои логические классы, или у меня должно быть только столько тестовых классов, сколько я считаю нужным?

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

Как я должен называть свои тестовые классы, методы и проекты (если они входят в разные проекты)

Мне нравится подчеркивать, что поведение - это то, что тестируется, поэтому я обычно называю тестовые классы после SUT.Например, если бы у меня был класс User, я бы назвал тестовый класс следующим образом:

public class UserBehavior

Методы должны иметь имена, описывающие поведение, которое вы ожидаете.

public void ShouldBeAbleToSetUserFirstName()

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

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

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

Следует ли разделять модульные и интеграционные тесты?

Да, модульные тесты должны быть изолированы от приемочных и интеграционных тестов.Разделение проблем применимо и к тестам.

Есть ли веская причина не иметь 100% тестового покрытия?

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

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

Другие советы

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

Мы запускаем тесты в том же проекте, в подпространстве имен под названием "UnitTes".

Наши тестовые классы отражают класс logic, чтобы упростить отслеживание того, где находятся тесты по отношению к тому, что они тестируют

Классы называются так же, как логический класс, который они тестируют, методы называются в соответствии со сценарием, который они тестируют.

Мы пишем тесты только для общедоступных и внутренних методов (тесты находятся в одном проекте) и стремимся к 95% охвату класса.

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

100% слишком сложно достигать постоянно.Мы стремимся к 95%-ному результату.Также уменьшается отдача от того, сколько времени потребуется, чтобы получить эти последние 5% и что на самом деле получится.

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

Я с нетерпением жду возможности увидеть, что другие скажут по этому поводу!

Ответ Джоша точен - всего лишь одно уточнение:

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

Не пересекайте балки.Если ты это сделаешь, произойдут плохие вещи.

Я настоятельно рекомендую вам прочитать Разработка, основанная на тестировании:На примере и Разработка, основанная на тестировании:Практическое Руководство Слишком много вопросов для одной темы

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

По порядку:

  • Нет, обычно лучше всего включать их в отдельный проект;если только вы не хотите иметь возможность запускать диагностику во время выполнения.
  • Идеальным является 100% покрытие кода, что означает каждую строку кода в каждой подпрограмме в каждом классе.
  • Я использую ClassnameTest, ClassnameTest.MethodNameTestnumber
  • Все.
  • Я бы сказал, да, поскольку интеграционные тесты не нужно запускать, если модульные тесты завершаются неудачей.
  • Простые свойства, которые просто устанавливают и получают поле, не нуждаются в проверке.

Должны ли тесты быть в том же проекте, что и логика приложения?

Это зависит от обстоятельств.В любом случае есть компромиссы.

Хранение этого в одном проекте требует дополнительной пропускной способности для распространения вашего проекта, дополнительного времени сборки и увеличивает объем установки, а также упрощает ошибку, связанную с производственной логикой, которая зависит от тестового кода.

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

Насколько важны эти различные затраты, зависит от проекта, поэтому универсального ответа нет.

Должен ли я иметь тестовые классы, отражающие мои логические классы, или у меня должно быть только столько тестовых классов, сколько я считаю нужным?

Нет.

У вас должны быть тестовые классы, которые допускают хорошо продуманный тестовый код (т. е.минимальное дублирование, четкое намерение и т.д.).

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

Как я должен называть свои тестовые классы, методы и проекты (если они входят в разные проекты)

Вы должны назвать их так, чтобы:

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

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

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

Следует ли разделять модульные и интеграционные тесты?

Это зависит от выбранного вами фреймворка (ов) тестирования.Делайте то, что лучше всего работает с вашими фреймворками тестирования и делает это так, чтобы:

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

Есть ли веская причина не иметь 100% тестового покрытия?

Да, на то есть веская причина.Строго говоря, “100% тестовое покрытие” означает, что каждая возможная ситуация в вашем коде отработана и протестирована.Это просто непрактично практически для любого проекта.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top