Как записать хорошие Модульные тесты? [закрытый]

Если вы управляете списками и пишете функциональный код в Emacs, установите библиотеку dash.el . Тогда вы можете использовать функцию -sum :

(-sum '(1 2 3 4 5)) ; => 15

41
задан Yeo 30 August 2015 в 16:16
поделиться

10 ответов

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

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

Две книги, которые я нашел полезными:

Разработка через тестирование в Microsoft .NET

Практический взгляд на разработку через тестирование, основанный на оригинальной книге Кента Бекса по TDD.

Pragmatic Unit Тестирование с помощью C # и nUnit

Сразу становится понятно, что такое модульное тестирование. и как его применять.

В ответ на ваши вопросы:

  1. Модульный тест, с практической точки зрения, - это единственный метод в классе, который содержит ровно столько кода, чтобы проверить один аспект / поведение вашего приложения. Поэтому у вас часто будет много очень простых модульных тестов, каждый из которых тестирует небольшую часть кода вашего приложения. Например, в nUnit вы создаете класс TestFixture, содержащий любое количество тестовых методов. Ключевым моментом является то, что тесты «проверяют единицу» вашего кода, то есть наименьшую (разумную) единицу, насколько это возможно. Вы не тестируете базовый API, который используете, а только код, который вы написали.

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

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

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

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

In .NET I strongly recommend "The Art of Unit Testing" by Roy Osherove, it is very comprehensive and full of good advice.

2
ответ дан 27 November 2019 в 00:55
поделиться

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

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

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

Модульный тест - это фрагмент кода, который запрашивает «единицу» вашего кода для выполнения операции, затем проверяет, действительно ли операция была выполнена и результат соответствует ожиданиям. Если результат неправильный, возникает / регистрируется ошибка.

Итак, позвольте нам сказать, что у меня есть класс с именем «Комплексные числа» с некоторыми методами в это (позволяет сказать найти сопряженное, перегруженный оператор присваивания и перегруженный оператор умножения. Какими должны быть типовые тестовые примеры для такой класс? Есть ли методология для выбора тестовых примеров?

В идеале вы должны протестировать весь код.

  • при создании экземпляра класс, он создается с правильным значения по умолчанию

  • , когда вы просите его найти конъюгаты, он действительно находит правильный (также тестовые пограничные случаи, такие как сопряжены для нуля)

  • когда вы присваиваете значение, значение назначается и отображается правильно

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

Есть ли их какие-либо рамки, которые могут создать для меня модульные тесты или мне нужно написать свой собственный класс для тестов?

См. CppUnit

Я вижу вариант «Тест» в Visual Studio 2008, но так и не заработал.

Не уверен в этом. Я не использовал VS 2008, но он может быть доступен только для .NET.

Каковы критерии для тестов модулей? Должен ли быть юнит-тест для каждого и каждая функция в классе? Является ли имеет смысл иметь модульные тесты для каждого и каждый класс?

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

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

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

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

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

Для дальнейшего чтения / документации просмотрите «внедрение зависимостей» и заглушки методов, которые используются в модульном тестировании и TDD.

2
ответ дан 27 November 2019 в 00:55
поделиться
  1. При проектировании, основанном на тестах, обычно сначала нужно написать тесты. Они должны охватывать операции, которые вы фактически используете / собираетесь использовать. Т.е. они не должны существовать, если они не нужны клиентскому коду для выполнения своей работы. Выбор тестовых примеров - это искусство. Есть очевидные вещи, такие как проверка граничных условий, но, в конце концов, никто не нашел действительно надежного, систематический способ гарантировать, что тесты (единичные или иные) охватывают все важные условия.

  2. Да, есть рамки. Вот несколько наиболее известных:
    Boost Unit Test Framework
    CPPUNit

    CPPUnit - это порт JUnit, поэтому те, кто раньше использовал JUnit, вероятно, сочтут его удобным. В противном случае я бы рекомендовал Boost - у них также есть Test Library , чтобы помочь писать отдельные тесты - скорее, удобное дополнение.

  3. Модульных тестов должно быть достаточно, чтобы убедиться, что код работает . Если (например) у вас есть частная функция, которая используется внутри компании, вам обычно не нужно тестировать ее напрямую. Вместо этого вы тестируете все, что предоставляет открытый интерфейс. Пока это работает правильно, внешний мир не должен заниматься своей работой. Конечно, в некоторых случаях это ' s легче тестировать маленькие кусочки, и когда это так, это совершенно законно - но в конечном итоге вы заботитесь о видимом интерфейсе, а не о внутреннем устройстве. Безусловно, следует протестировать весь внешний интерфейс, и обычно следует выбирать тестовые примеры для проверки путей прохождения кода. Опять же, модульные тесты ничем не отличаются от других типов. В основном это просто более систематический способ применения обычных методов тестирования.

2
ответ дан 27 November 2019 в 00:55
поделиться

Модульные тесты - это просто способ проверить заданный корпус кода, чтобы убедиться, что определенный набор условий приводит к ожидаемому набору результатов. Как указывает Стивен, эти «упражнения» должны проверяться по ряду критериев («BICEP»). Да, в идеале вы должны протестировать все свои классы и все методы в этих классах, хотя всегда есть место для суждения: тестирование не должно быть самоцелью, а должно поддерживать более широкие цели проекта.

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

Во-первых, возьмите копию NUnit . Это бесплатно, легко установить и с ним легко работать. Если вам нужна документация, ознакомьтесь с Pragmatic Unit Testing in C # с NUnit.

Затем перейдите на http://www.testdriven.net/ и получите копию TestDriven .сеть. Он устанавливается в Visual Studio 2008 и предоставляет вам доступ по щелчку правой кнопкой мыши к полному набору инструментов тестирования, включая возможность запускать тесты NUnit для файла, каталога или проекта (обычно тесты пишутся в отдельном проекте). Вы также можете запускать тесты с отладкой или, что лучше всего, запускать все тесты с копией NCover. NCover покажет вам точно , какой код выполняется, чтобы вы могли понять, где вам нужно улучшить охват тестированием. TestDriven.net стоит 170 долларов за профессиональную лицензию, но, если вы похожи на меня, он очень быстро станет неотъемлемым инструментом в вашем наборе инструментов. Тем не мение,

1
ответ дан 27 November 2019 в 00:55
поделиться

Я не могу ответить на ваш вопрос о Visual Studio 2008, но я знаю, что Netbeans имеет несколько интегрированных инструментов, которые вы можете использовать.

  1. Покрытие кода два позволяет вам увидеть, какие пути были проверены и какая часть кода фактически покрыта модульными тестами.
  2. Он имеет встроенную поддержку модульных тестов.

Что касается качества тестов, я немного позаимствовал из « Pragmatic Unit Testing in Java with JUnit » Эндрю Ханта и Дэвид Томас:

Модульное тестирование должно проверять BICEP : Граница B , I обратная связь, C проверка Росс, E условия ошибки и P работоспособность.

Также качество тестов определяется A-TRIP : A автоматическая, T полная, R повторяемая, I независимая и P профессиональная.

1
ответ дан 27 November 2019 в 00:55
поделиться

Купите книгу «Тестовые шаблоны xUnit: рефакторинг тестового кода». Очень хорошо. Он охватывает как стратегические решения высокого уровня, так и тестовые шаблоны низкого уровня.

0
ответ дан 27 November 2019 в 00:55
поделиться

Вот кое-что о том, когда не следует писать модульные тесты (то есть, когда это жизнеспособно и даже предпочтительнее пропускать модульное тестирование): Если нужно протестировать внутреннюю реализацию, или тестировать только публичное поведение?

Краткий ответ:

  • Когда можно автоматизировать интеграционные тесты (потому что важно иметь автоматизированные тесты, но эти тесты не обязательно должны быть модульными)
  • Когда это дешево для запуска набора интеграционных тестов (бесполезно, если запуск занимает два дня или если вы не можете позволить каждому разработчику иметь доступ к оборудованию для интеграционных тестов)
  • Когда нет необходимости обнаруживать ошибки перед интеграцией тестирование (которое частично зависит от того, разрабатываются ли компоненты отдельно или постепенно)
0
ответ дан 27 November 2019 в 00:55
поделиться

В настоящее время разработка через тестирование - это подход для легкого управления большими проектами программного обеспечения.

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

Что такое модульный тест?

Модульный тест - это фрагмент кода, который проверяет поведение одного модуля. То, как определяется одна единица, зависит от людей. Но в целом они:

  1. Быстро запускаются
  2. Независимы друг от друга
  3. Проверяйте только небольшую часть (единицу;) вашей кодовой базы.
  4. Двоичный результат - то есть проходит или не проходит.
  5. Должен тестировать только один результат модуля (для каждого результата создайте отдельный модульный тест)
  6. Повторяемый

Есть ли у них какие-либо структуры, которые могут создавать модульные тесты.

Для написания тестов - Да, но я ' я никогда не видел, чтобы кто-нибудь сказал о них что-нибудь хорошее.
Чтобы помочь вам писать и запускать тесты, целая куча из них.

Должен ли быть модульный тест для каждой функции в классе?

У вас есть несколько разных лагерей - стопроцентные скажут да. Каждый метод должен быть протестирован, и у вас должно быть 100% покрытие кода . Другая крайность заключается в том, что модульные тесты должны охватывать только те области, в которых вы даже сталкиваетесь с ошибками или ожидаете их найти. Золотая середина (и моя позиция) - это модульное тестирование всего, что «не так просто сломать». Сеттеры / геттеры и все, что просто вызывает единственный другой метод. Я стремлюсь обеспечить покрытие кода 80% и низкий коэффициент CRAP (так что маловероятно, что я был непослушным и решил не тестировать что-то, так как это было «слишком сложно для тестирования»).

Книга это помогло мне "получить" модульные тесты JUnit в действии . Извините, я мало что делаю в мире C ++, поэтому не могу предложить альтернативу на основе C ++.

0
ответ дан 27 November 2019 в 00:55
поделиться

While you've already accepted an answer to your question I'd like to recommend a few other books not yet mentioned:

  • Working Effectively with Legacy Code - Michael Feathers - As far as I know this is the only book to adequately tackle the topic of turning existing code that wasn't designed for testability into testable code. Written as more of a reference manual, its broken down into three sections: An overview of the tools and techniques, A series of topical guides to common road blocks in legacy code, A set of specific dependency breaking techniques referenced throughout the rest of the book.
  • Agile Principles, Patterns, and Practices - Robert C. Martin - Examples in java, there is a sequel with examples in C#. Both are easy to adapt to C++
  • Clean Code:A Handbook of Agile Software Craftsmanship - Robert C. Martin - Martin describes this as a prequel to his APPP books and I would agree. This book makes a case for professionalism and self-discipline, two essential qualities in any serious software developer.

The two books by Robert (Uncle Bob) Martin cover much more material than just Unit testing but they drive home just how beneficial unit testing can be to code quality and productivity. I find myself referring to these three books on a regular basis.

7
ответ дан 27 November 2019 в 00:55
поделиться
Другие вопросы по тегам:

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