Подтвердить что ты не робот

Запуск проекта TDD с нуля

Я прочитал много вопросов и ответов на TDD и модульное тестирование на SO, но я ничего не нашел для ответа на этот вопрос: с чего начать?

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

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

Скажем, просто чтобы иметь контекст, о котором нужно подумать, мне нужно разработать интернет-приложение, ориентированное на документ, с небольшим потоком работы и... что-то еще. Но пусть начнется с самого начала: во-первых, я хочу создать простую страницу, в которой перечислены все документы (метаданные), хранящиеся в таблице в БД (довольно просто, мм?). Какой первый тест я бы написал? Скажем, что я использую Hibernate для доступа к db... я бы проверил ipothetical метод getAllDocuments()? Но следует ли использовать макет для замены Hibernate? Итак, что я тестирую?

Я немного запутался здесь... Кроме того, getAlDocuments(), вероятно, никогда не будет производственным методом... вся коллекция документов будет упорядочена и отфильтрована чем-то... это имеет смысл? Любое предложение будет оценено

Отредактировано:

После прочтения ваших ответов (и аналогичного потока в http://programmers.stackexchange.com) я прихожу с лучшим видением TDD, но у меня все еще есть дубт.

Я всегда, хотя TDD о создании unit test сначала... никогда не думал о сквозном тесте. Но позвольте мне спросить: TDD говорит, что вы должны написать тест и увидеть ошибку компиляции; то вы создаете класс и метод, и вы получаете отказ теста; то вы реализуете метод и передаете тест. Вы не можете писать код до тех пор, пока не завершится тест; вы не можете написать еще один тест, пока все испытания не пройдут. Я здесь?

Как я могу сделать сквозной тест в качестве моего первого теста? Я должен написать весь код на всем слое, чтобы пройти этот тест. Но тогда у меня будет множество классов и методов, которые будут проверены моим сквозным тестом (не следует ли мне называть это интеграционным тестом?). Это означает, что мне больше не понадобится unit test, потому что у меня уже есть тест, который охватывает мой код. И я не могу написать тест, который уже проходит, это против TDD-pratice.

Помогите мне понять этот дальнейший шаг вперед.

4b9b3361

Ответ 1

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

Вы начинаете новый проект, и у вас, вероятно, есть набор функций. У вас должны быть некоторые критерии приемлемости для функций, которые вы собираетесь реализовать. Эти критерии могут определять ваши тесты верхнего уровня. Пусть начнется либо сквозной тест (это может быть довольно сложно иногда, потому что он включает в себя пользовательский интерфейс, который еще не существует) или интеграционный тест для этих критериев приемки. После того, как у вас будет тест, который не работает, вы продолжите реализацию функций, связанных с большим тестом, но каждая из этих функций будет снова управляться либо интеграцией, либо unit test. Функция завершается, если проходят все тесты верхнего уровня.

Если вы пропустите большие тесты (сквозной, интеграционный), вы разработаете набор хорошо протестированных модулей, которые либо не будут работать, если они будут объединены вместе, либо ваша архитектура будет не очень хорошей из-за локальной области, определенной модульными тестами, Интеграция и сквозные тесты дают вам глобальную область.

Это описывается большим примером (Java) в книге Растущее объектно-ориентированное программное обеспечение, управляемое тестами.

Ответ 2

Я обычно начинаю сверху вниз. В вашем случае я бы начал с написания логики контроллера вашей новой страницы. К контроллеру я имею в виду уровень кода чуть ниже пользовательского интерфейса, издеваясь над всем ниже. Затем напишите сервисный уровень (если он у вас есть), высмеивая слой данных. Наконец, протестируйте слой данных также с помощью mocks базовых классов (может быть ISession в вашем случае). Наконец, я бы написал один тест интеграции каждого из методов уровня данных и построил страницу (html).

Ответ 3

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

public class DocumentManagementTest {
  @Test public void allowsDocumentUploads() {
    DocumentManagement dm = new DocumentManagement();
    Reader mockReader = new MockDocumentReader();

    Document result = dm.createDocument("Document name", mockReader);

    assertEquals("Document name", result.getName());
    assertEquals(0, result.getTags().size());
    assertTrue(mockReader.fileWasRead);
  }
}

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

@Test public void allowsDocumentRenames() { ... }
@Test public void allowsAddingTagsToExistingDocuments() { ... }
@Test public void showsErrorWhenAddingDocumentThatAlreadyExists() { ... }

Как только вы создали такую ​​функцию, как createDocument, вы можете создать вокруг нее контроллер.

public void doPost(HttpServletRequest req, HttpServletResponse resp) {
  String name = req.getParameter("doc_name");
  Document d = docMgmt.createDocument(name, req.getInputStream());
  // Hand the newly created document to the view engine.
}

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

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

Ура!

Brandon

Ответ 4

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

Начните с одного класса? что должны делать его объекты? Как вы можете убедиться, что это сделано правильно? Это первый тест.

Вы также можете запустить без базы данных и хранить свои документы в плоском файле. Вы позже будете реорганизовывать базу данных. Затем вы можете начать с функции getAllDocuments().