Тестирование - номенклатура
Классы часто тестируются с использованием тестов, написанных с использованием синтаксиса следующего вида, который предоставляется большим набором тестовых сред (например, Ruby's Unit::Test; или, как в этом примере, MiniTest):
class TestLolcat < MiniTest::Unit::TestCase
def setup
@lolcat = Lolcat.new
end
def test_that_lolcat_can_have_cheezburger
assert_equal true, @lolcat.i_can_has_cheezburger?
end
end
или вместо этого с помощью тестов, написанных в синтаксисе второго рода, который обеспечивается перекрывающимся набором структур тестирования (например, RSpec; или, как в этом примере, снова MiniTest):
describe Lolcat do
before do
@lolcat = Lolcat.new
end
it "must be able to have cheezburger" do
@lolcat.i_can_has_cheezburger?.must_equal true
end
end
(Возможно, есть другие синтаксические семейства, которые также подходят для тестирования методов и атрибутов класса, но это те, которые меня интересуют.)
Что я хочу знать: каково правильное имя для каждого из этих двух синтаксических семейств?
Если вы хотите узнать больше о том, почему я спрашиваю, см. Ниже строки.
Причина, по которой я задаю этот вопрос, заключается в том, что поиск в Интернете не привел к очевидному согласию. Например, в документации MiniTest первый синтаксис, описанный выше, называется синтаксисом "модульного теста", а второй - синтаксисом "спецификации". Майкл Хартл, напротив, описывает методы класса и тесты атрибутов, написанные во втором виде синтаксиса, как "модульные тесты". Там, где тесты, написанные в этом синтаксисе, тестируют функциональность более высокого уровня, являющуюся результатом взаимодействия нескольких классов, он называет их "интеграционными тестами".
Я также видел, как люди описывают первый и второй типы синтаксиса как "Test::Unit style" и "RSPec-esque", соответственно, или синтаксис "TDD" и "BDD". Другие имена для синтаксиса второго типа включают " синтаксис, похожий на " должен " " и " синтаксис it ".
Мое понимание (которое смутно предполагает, что Хартл прав) заключается в следующем:
- TDD - это практика, а не синтаксис тестирования. В частности, это практика написания неудачного теста (например, модульного теста или интеграционного теста), затем кода для прохождения теста, затем рефакторинга, если необходимо, и затем перезапуска цикла.
- BDD также является практикой, но она делает некоторые ограниченные предписания о тестировании синтаксиса. В частности, это практика следования TDD, но с использованием "следует" в качестве первого слова в именах тестов и вложением кода тестирования для предоставления контекста, если это необходимо.
- Модульное тестирование - это практика, а не синтаксис тестирования. В частности, практика тестирования отдельных единиц кода (например, методы класса или атрибуты)
- Модульные тесты - это тесты, написанные в ходе модульного тестирования, независимо от используемого синтаксиса.
- Интеграционное тестирование - это практика, а не синтаксис тестирования. В частности, практика тестирования высокоуровневой функциональности, которая является результатом взаимодействия нескольких классов.
Однако, это все еще не совсем проясняет ситуацию. Очевидно, я не специалист по номенклатуре методов тестирования, типов тестов или синтаксисов тестов. Лучшими именами, которые я смог придумать для двух типов синтаксиса, которые я привел в качестве примеров выше, являются "синтаксис assert" и "it... do" синтаксис, соответственно. Если эти имена не используются повсеместно, мне нужен ваш совет, коллеги по Stackru!
4 ответа
Я не уверен, что есть приемлемое определение для каждого.
Мне нравится думать о них таким образом.
мини-тестовая версия - это скорее диссертация
версия rspec - это скорее спецификация
Последняя была придумана, чтобы отвлечь вас от акцента на "тест" и больше, чтобы исключить требования с точки зрения заинтересованных сторон.
Это могло бы прояснить ситуацию, если бы мы поделились немного историей о BDD и TDD.
Еще в 2003 году платформой модульного тестирования для TDD был JUnit. Дэн Норт начал писать JBehave вместо JUnit, используя "должен" вместо "тест" - так, синтаксис BDD. Теперь это не очень похоже на то, что вы делаете (и что делает RSpec) в Ruby, но, тем не менее, RSpec был создан как версия того же самого для Ruby. JBehave никогда не вкладывал тестовый код; он просто имел "должен" для примеров на уровне устройства, а затем некоторые другие gubbins для запуска полнофункциональных сценариев. Дэн перенес сценариста в Ruby, где он стал сценаристом RSpec, а затем, в конце концов, Cucumber.
Таким образом, синтаксис "это... должен" определенно является BDD на уровне устройства. Большинство людей знакомы с BDD как с полными системными сценариями, но это не то место, где BDD начинался. В настоящее время BDD на самом деле не единственная практика; это мини-методология, которая подходит для видения проекта - на случай, если вы столкнетесь с чем-то запутанным. А JBehave 2.0 был переписан для работы со сценариями и шагами и потерял тестирование на уровне модулей вместе с фальшивой структурой, потому что к тому времени JUnit и Mockito работали хорошо. Но, тем не менее, именно здесь "должен" начался.
Теперь... как только вы используете "должен" вместо "должен", вы теряете чувство неопределенности, которое обеспечивает "должен". Использование "следует" позволяет вам задавать множество вопросов, самый важный из которых "должен?" Таким образом, все, что использует "должен" вместо "должен", больше не является синтаксисом BDD; это гибрид.
Кстати, мы стараемся избегать слова "тест", когда говорим о BDD, поэтому они не являются модульными тестами, написанными в ходе тестирования; это примеры того, как будет вести себя класс, написанный в ходе разработки кода.
При работе с программным обеспечением необходимо различать " что " и " как ": что должна делать программа и как она работает.
ИМХО, важно иметь в виду разницу между ними на всех этапах разработки. Это различие поддерживает несколько принципов, например, кодирование по интерфейсу, дизайн, основанный на ответственности, проектирование по контракту и утверждениям, а также модульное тестирование.
Увы, не всегда так легко отделить два понятия. С классическими примерами, такими как сортировка, легко разобраться: существует несколько алгоритмов сортировки (как), которые все приводят к отсортированному набору элементов (что), которые могут быть легко выражены как утверждение, контракт, инвариант. Для бизнес-кода ситуация может стать менее понятной.
Я полагаю, что два синтаксиса достигают в основном одного и того же, но второй подход облегчает мышление в терминах "что", а не "как". Давайте рассмотрим два утверждения:
установить значение% 2 = 0
значение должно быть четным
Они приводят в действие один и тот же инвариант, но 2-й делает более упор на "что" и является более читабельным для человека.
Smalltalk использует, например, should
формулировки, но тесты являются императивным кодом, как в Ruby.
SetTestCase>>testAdd
empty add: 5.
self should: [empty includes: 5]
К сожалению, мое отступление все еще не отвечает на ваш вопрос и было слишком долго для комментария.
Для методов тестирования не существует общепринятых имен синтаксиса. Большинство инструментов модульного тестирования поощряют определенные соглашения, например, JUnit рекомендует начинать все имена методов тестирования с "test", который теперь стал ненужным с помощью аннотации @Test.
Большинство инструментов модульного тестирования предлагают определенное соглашение, с которым согласны разработчики. Имена методов тестирования не имеют синтаксиса, поскольку целевой аудиторией являются разработчики, которые должны легко понять, что делает метод тестирования.
Если вы ищете определения в контексте тестирования, взгляните на книгу Gerard Meszaros "Тестовые шаблоны xUnit". Автор предлагает некоторые разъяснения по различным терминам. На его определение "двойников теста" ссылались несколько раз.