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

Мотивация

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

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

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

Обсуждение

Для некоторых это покажется слишком сложно и будет трудно решить несколько проблем в один момент. Две проблемы из списка можно легко отделить от остальных: “Каков будет правильный результат?” и “Как проверить корректность результата?”.

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

testCompleteTransaction() {
  assertTrue(reader.isClosed());
  assertEquals(abc, reply.contents())
}

Откуда мы должны будем получить ответ? Разумеется, что от сокета.

testCompleteTransaction() {
  Socket reader = Socket(localhost, defaultPort())
  Buffer reply = reader.contents();
  assertTrue(reader.isClosed());
  assertEquals(abc, reply.contents())
}

Но перед этим всем мы должны открыть соединение с сервером:

testCompleteTransaction() {
  Server writer = Server(defaultPort(), "abc")
  Socket reader = Socket(localhost, defaultPort())
  Buffer reply = reader.contents();
  assertTrue(reader.isClosed());
  assertEquals(abc, reply.contents())
}

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