LiveServerTestCase зависает при вызове python-запросов в представлении django

Я пишу приложение Django, которое использует REST api, который я создал. Цель состоит в том, чтобы доказать использование вариантов использования api с помощью веб-приложения. На мой взгляд, поэтому я вызываю api, используя библиотеку python-запросов следующим образом:

def my_view_method(request):
    if request.method == 'POST':
    form = MyForm(request.POST)
    if form.is_valid():
        data = form.cleaned_data
        data_to_post = {
            'fieldA': data.get('fieldA_in_form'),
            'fieldB': data.get('fieldB_in_form'),
        }
        post_url = "http://%s/%s/" % (request.get_host(), 'entries')
        logger.info("request api url: "+ post_url)
        r = requests.post(post_url, data=data_to_post)
        return HttpResponseRedirect('/')
    else:
        form = MyForm()

    return render(request, 'myview.html', { 'form': form })

Я проверил с помощью Unit Tests, что POSTing to/entries/с достоверными данными приводит к правильным обновлениям базы данных.

url = '/entries/'
#verify initial db state
data = { 'fieldA': value1, 'fieldB': value2 }
response = self.client.post(url, data, format='json')
# verify db was updated

В моих функциональных тестах я использую LiveServerTestCase и взаимодействую с Формой. Когда тест отправляет форму, на вкладке браузера отображается "Подключение..." в заголовке, и тестовый пример зависает. Это было не так, когда я напрямую взаимодействовал с базой данных вместо вызова api с использованием запросов, поэтому это должно быть источником задержки.

Есть ли что-то о том, как работает LiveServerTestCase, что я здесь не понимаю?

Ответ 1

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

Источник говорит, что он будет обрабатывать один запрос за раз, но затем он говорит "без блокировки", так что это неоднозначно...

Думаю, вам лучше отказаться от LiveServerTestCase и просто запустить собственный тестовый бегун. Вы можете использовать setUp для вращения runserver в отдельном процессе и tearDown до reset базы данных (manage.py flush?). Если вы хотите использовать тестовую базу данных, вы можете использовать другую settings.py или просто переместить "настоящую" базу данных в сторону на протяжении всего теста...

Ответ 2

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

Вам даже не нужно это делать, имеет смысл тестировать API напрямую, а не расширять веб-сервер через Django.

Это описание LiveServerTestCase из документации здесь

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

Нет необходимости даже инициализировать приложение Django, если вы хотите протестировать сам API.

Один из методов тестирования, который мне нравится отслеживать, - это методология интеграции компонентов, описанная в Wikipedia здесь.

В этом примере мы будем тестировать приложение Django (front end) отдельно от уровня сервиса (API). Вы можете использовать API при тестировании интерфейса, но существует разделение для определения того, как вы пишете тесты.

Поскольку API является приложением Flask, я бы использовал Flocks, встроенный в инструменты тестирования, описанные здесь.

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

Чтобы помочь в тестировании пользовательского интерфейса, вы можете использовать API как часть вашей программы test fixture/ setUp, чтобы сохранить себя от использования пользовательского интерфейса, чтобы добавить любые тестовые данные, необходимые для выполнения. Однако, если вы хотите протестировать сам API, то выполнение его через клиент Django не будет работать из-за проблемы, упомянутой выше.