Запуск проекта TDD с нуля - PullRequest
17 голосов
/ 16 июня 2011

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

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

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

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

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

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

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

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

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

Помогите мне понять этот шаг вперед, пожалуйста

Ответы [ 4 ]

14 голосов
/ 16 июня 2011

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

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

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

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

2 голосов
/ 17 июня 2011

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

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, вы будете постепенно наращивать систему с большим охватом тестирования и довольно хорошими ОО-свойствами.

Ура!

Brandon

2 голосов
/ 16 июня 2011

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

1 голос
/ 16 июня 2011

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

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

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

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