zer*_*dge 4 python django django-testing pytest pytest-django
假设我正在Django应用程序中测试RSS feed视图,这是我应该怎么做的吗?
def test_some_view(...):
...
requested_url = reverse("personal_feed", args=[some_profile.auth_token])
resp = client.get(requested_url, follow=True)
...
assert dummy_object.title in str(resp.content)
Run Code Online (Sandbox Code Playgroud)
是reverse-ing然后将其传递client.get()给正确的测试方法?我认为这比以前简单地.get()设置URL 更干燥,而且更适合未来使用。
我应该断言这dummy_object就是这种回应吗?
我在这里使用str响应对象的表示形式进行测试。与使用时相比,selenium什么时候是个好习惯?我知道,例如,可以更轻松地验证obj或属性(如dummy_object.title)是否封装在H1标签中。在另一方面,如果我不关心如何与obj表示,它的速度更快做像上面。
重新评估我的评论(没有仔细阅读问题,却忽略了RSS feed的内容):
- 是
reverse-ing然后将其传递client.get()给正确的测试方法?我认为这比以前简单地.get()设置URL 更干燥,而且更适合未来使用。
我同意这一点-从Django的角度来看,您正在测试您的视图,而不关心它们映射到的确切端点是什么。reverse因此,使用IMO是明确而正确的方法。
- 我应该断言这
dummy_object就是这种回应吗?
您必须在这里注意。response.content是一个字节字符串,因此断言dummy_object.title in str(resp.content)很危险。考虑以下示例:
from django.contrib.syndication.views import Feed
class MyFeed(Feed):
title = 'äöüß'
...
Run Code Online (Sandbox Code Playgroud)
在urls以下位置注册了提要:
urlpatterns = [
path('my-feed/', MyFeed(), name='my-feed'),
]
Run Code Online (Sandbox Code Playgroud)
测试:
@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
Run Code Online (Sandbox Code Playgroud)
一个会失败,另一个不会因为正确的编码处理而失败。
至于检查本身,我个人更喜欢将内容解析为一些有意义的数据结构,而不是使用原始字符串,即使是简单的测试也是如此。例如,如果您要检查text/html响应中的数据,那么编写该文件就不会有太多开销
soup = bs4.BeautifulSoup(content, 'html.parser')
assert soup.select_one('h1#title-headliner') == '<h1>title</h1>'
Run Code Online (Sandbox Code Playgroud)
要么
root = lxml.etree.parse(io.StringIO(content), lxml.etree.HTMLParser())
assert next(root.xpath('//h1[@id='title-headliner']')).text == 'title'
Run Code Online (Sandbox Code Playgroud)
不只是
assert 'title' in content
Run Code Online (Sandbox Code Playgroud)
但是,调用解析器是更明确的(例如,您不会意外地测试中的页面元数据中的标题head),并且还会对数据完整性进行隐式检查(例如,您知道有效负载确实是有效的HTML,因为已成功解析)。
以您的示例为例:如果使用RSS feed,我将仅使用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'
Run Code Online (Sandbox Code Playgroud)
在这里,我使用的lxml是stdlib的更快的印象xml。将内容解析为XML树的优点还在于,解析器从字节串读取数据,并注意编码处理-因此您不必自己解码任何内容。
或使用类似这样的高级命令atoma,它是专门用于RSS实体的不错的API,因此您不必与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'
Run Code Online (Sandbox Code Playgroud)
- ...当它是一个很好的做法用来做对比
selenium?
简短答案-您不需要它。在阅读您的问题时,我并没有特别注意,在撰写评论时,请记住HTML页面。关于这selenium一点-这个库处理所有低级的东西,所以当测试开始计数时(通常,它们做得很快),编写
uri = reverse('news-feed')
resp = client.get(uri)
root = parser.parse(resp.content)
assert root.query('some-query')
Run Code Online (Sandbox Code Playgroud)
并拖延进口变得太麻烦了,因此selenium可以将其替换为
driver = WebDriver()
driver.get(uri)
assert driver.find_element_by_id('my-element').text == 'my value'
Run Code Online (Sandbox Code Playgroud)
当然,使用自动浏览器实例进行测试还具有其他优势,例如准确查看用户在实际浏览器中看到的内容,允许页面执行客户端javascript等。如果针对RSS feed的selenium使用进行测试是过大的,并且Django的测试工具绰绰有余。
| 归档时间: |
|
| 查看次数: |
382 次 |
| 最近记录: |