Важное примечание : То, что вы описываете, не является модульным тестом.Он не тестирует одну единицу.Он тестирует целую кучу вещей, начиная с 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.Требуется внести изменения как минимум в три вещи:
- обработчик представления поста
- получить обработчик представления
- модель
Во многих случаяхимеет смысл разделить его, сначала создав тест для самой модели.Тест, который не будет работать с тестовым клиентом, но будет выглядеть так:
def test_entity(self):
entity = Entity.objects.create()
entity = Entity.objects.get(entity.id)
assert_that(entity.id, not_none())
Затем вы добавляете модель.Убедитесь, что test_entity
пройдено и только после этого измените представление, чтобы использовать вашу (уже протестированную) модель.
Я надеюсь, что это дает представление о том, как решить эту проблему.