Разработка через тестирование с помощью Django - PullRequest
0 голосов
/ 18 сентября 2018

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

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

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

Какой здесь предложенный подход?Может быть, сначала написать более простой тест, а затем модифицировать его после того, как будет реализован достаточный уровень производственного кода?

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Важное примечание : То, что вы описываете, не является модульным тестом.Он не тестирует одну единицу.Он тестирует целую кучу вещей, начиная с django url wiring, views и заканчивая моделями.Это интеграционные тесты.Во-вторых, не создавайте тест, который использует внешний API (или тестовый клиент, который в основном одинаковый) для создания данных, но проверяет, что объект был создан путем перехода непосредственно в БД.Это не хорошо.Если вы создаете данные через некоторый API, вы должны использовать API того же уровня, чтобы проверить, созданы ли данные.Так что мое объяснение будет говорить об этом подходе.

То, что вы описываете, является распространенной проблемой, когда вы начинаете с TDD.

Важные вещи о TDD: вы

1008 * делать небольшие шаги рефакторинг после теста зеленый (включая рефакторинг теста)

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

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

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

Это похоже (но с существенным отличием) на то, что вы написали:

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

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

В этом конкретном случае вы можете реализовать его в следующие шаги:

1 Создать тест, который использует тестовый клиент

def test_entity_creation(self):
    post_result = test_client.post(POST_URL, {})

    get_result = test_client.get(get_entity_url_from(post_result))

    assert_that(get_result, not_none())

У вас есть тест, которыйне удается, но строка кода не написана.Обратите внимание, что данные еще не переданы, и проверка очень проста.

2 Создать проводку URL и пустое представление

Сделайте так, чтобы пройти тест.Вам нужно очень мало изменений в коде, и представление не будет возвращать много, если что-нибудь.View может вернуть некоторые жестко закодированные json / dict на этом этапе.

3.1 Проверьте, что сгенерирован id объекта

def test_entity_creation(self):
    post_result = test_client.post(POST_URL, {})

    get_result = test_client.get(get_entity_url_from(post_result))

    assert_that(get_result, not_none())
    assert_that(get_result, has_field('id', not_none()))

Вы можете сделать этот тест работающим, добавив id к жестко закодированному dict.

3.1 Убедитесь, что генерируется уникальный идентификатор сущности

Добавьте новый тест, который проверяет уникальность идентификаторов:

def test_create_generates_unique_id(self):
    post_result1 = test_client.post(POST_URL, {})
    post_result2 = test_client.post(POST_URL, {})

    assert_that(get_id(post_result1), not_(equal_to(get_id(post_result2)))

4 Добавьте модель только с идентификатором

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

5 Добавьте одно поле к вашему тесту

def test_entity_creation(self):
    post_result = test_client.post(POST_URL, {'field': 'value'})

    get_result = test_client.get(get_entity_url_from(post_result))

    assert_that(get_result, not_none())
    assert_that(get_result, has_field('field', 'value'))

Добавьте поле в модель и сделайтепроход теста.

6 Продолжайте выполнять TDD

Добавьте дополнительные тесты и производственный код.

Еще несколько мыслей

Шаг 4 может быть слишком большим, как дляодин цикл TDD.Требуется внести изменения как минимум в три вещи:

  1. обработчик представления поста
  2. получить обработчик представления
  3. модель

Во многих случаяхимеет смысл разделить его, сначала создав тест для самой модели.Тест, который не будет работать с тестовым клиентом, но будет выглядеть так:

def test_entity(self):
    entity = Entity.objects.create()

    entity = Entity.objects.get(entity.id)

    assert_that(entity.id, not_none())

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

Я надеюсь, что это дает представление о том, как решить эту проблему.

0 голосов
/ 18 сентября 2018

В Django подход всегда заключается в воссоздании рабочей среды для тестирования и подготовки.При тестировании данные являются поддельными, при постановке данные «старые» или очень похожи на производственные.

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