Переоценка моего комментария (не внимательно прочитал вопрос и пропустил материал RSS):
- Является ли
reverse
-ing и затем передача его в client.get()
правильным способом проверки? Я думал, что это СУХОЕ и более перспективно для будущего, чем просто .get()
с помощью URL.
Я бы согласился с этим - с точки зрения Джанго, вы проверяете свои взгляды и не заботитесь о том, с какими точными конечными точками они сопоставляются. Таким образом, использование reverse
является ИМО ясным и правильным подходом.
- Должен ли я утверждать, что
dummy_object
находится в ответе таким образом?
Вы должны обратить внимание здесь. response.content
- строка байтов, поэтому утверждение dummy_object.title in str(resp.content)
опасно. Рассмотрим следующий пример:
from django.contrib.syndication.views import Feed
class MyFeed(Feed):
title = 'äöüß'
...
Зарегистрированный канал в urls
:
urlpatterns = [
path('my-feed/', MyFeed(), name='my-feed'),
]
Тесты:
@pytest.mark.django_db
def test_feed_failing(client):
uri = reverse('news-feed')
resp = client.get(uri)
assert 'äöüß' in str(resp.content)
@pytest.mark.django_db
def test_feed_passing(client):
uri = reverse('news-feed')
resp = client.get(uri)
content = resp.content.decode(resp.charset)
assert 'äöüß' in content
Один не удастся, другой - нет из-за правильной обработки кодировки.
Что касается самой проверки, лично я всегда предпочитаю синтаксический анализ содержимого для какой-либо значимой структуры данных, а не для работы с необработанной строкой даже для простых тестов. Например, если вы проверяете данные в ответе text/html
, при написании * 1036 это не намного увеличивает накладные расходы
soup = bs4.BeautifulSoup(content, 'html.parser')
assert soup.select_one('h1#title-headliner') == '<h1>title</h1>'
или
root = lxml.etree.parse(io.StringIO(content), lxml.etree.HTMLParser())
assert next(root.xpath('//h1[@id='title-headliner']')).text == 'title'
чем просто
assert 'title' in content
Однако, вызов парсера является более явным (вы не будете случайно проверять, например, заголовок в метаданных страницы в head
), а также неявно проверяет целостность данных (например, вы знаете, что полезная нагрузка действительно является корректным HTML потому что разобрался успешно).
К вашему примеру: в случае подачи RSS, я бы просто использовал анализатор XML:
from lxml import etree
def test_feed_title(client):
uri = reverse('my-feed')
resp = client.get(uri)
root = etree.parse(io.BytesIO(resp.content))
title = root.xpath('//channel/title')[0].text
assert title == 'my title'
Здесь я использую lxml
, что является более быстрым значением stdlib's xml
. Преимущество синтаксического анализа содержимого в дереве XML заключается также и в том, что анализатор читает из байтовых строк, заботясь об обработке кодирования, поэтому вам не нужно ничего декодировать самостоятельно.
Или используйте что-то высокоуровневое, например atoma
, которое имеет хороший API специально для RSS-сущностей, так что вам не придется бороться с селекторами XPath:
import atoma
@pytest.mark.django_db
def test_feed_title(client):
uri = reverse('my-feed')
resp = client.get(uri)
feed = atoma.parse_atom_bytes(resp.content)
assert feed.title.value == 'my title'
- ... Когда это хорошая практика по сравнению с использованием
selenium
?
Краткий ответ - вам это не нужно. Я не обращал особого внимания при чтении вашего вопроса и имел в виду HTML-страницы при написании комментария. Что касается этого замечания selenium
- эта библиотека обрабатывает все вещи низкого уровня, поэтому, когда тесты начинают накапливаться в счетчике (и, как правило, они делают это довольно быстро), пишется
uri = reverse('news-feed')
resp = client.get(uri)
root = parser.parse(resp.content)
assert root.query('some-query')
и перетаскивание импорта становится слишком хлопотным, поэтому selenium
может заменить его на
driver = WebDriver()
driver.get(uri)
assert driver.find_element_by_id('my-element').text == 'my value'
Конечно, у тестирования с автоматическим экземпляром браузера есть и другие преимущества, такие как просмотр именно того, что пользователь увидит в реальном браузере, разрешение страницам выполнять клиентский JavaScript и т. Д. Но, конечно, все это относится главным образом к тестированию HTML-страниц. ; в случае тестирования по RSS-каналу selenium
использование является излишним, а инструментов тестирования Django более чем достаточно.