Flask Unit Testing and not understanding my fix for "TypeError: a bytes-like object is required, not 'str'"
Flask Unit Testing and not understanding my fix for "TypeError: a bytes-like object is required, not 'str'"
我目前正在构建一个小型 Web 应用程序来提高我的技能,作为其中的一部分,我正在尝试全面采用最佳实践、测试、CI、架构良好、代码简洁等那个。在过去的几次工作中,我一直在努力对我的根路由进行测试,而不是通过路由函数 returning 一个字符串,我正在渲染一个模板,我已经让它工作了,但我不明白为什么会这样,这让我很困扰。
主要是 b 的使用,在我的断言字符串之前,我认为这与我呈现的不是字符串,而是 html 表示形式有关,类似于return 和 print 之间的区别,但我很朦胧,希望有人教我。
我要问的是test_homepage_response函数的第4行。以及它是如何运作的。特别是关于这个错误,我得到:
正在 return 编辑的错误:
ERROR: test_home_welcome_return (tests.home_page_tests.HomePageTestClass)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/xibalba/code/reel/tests/home_page_tests.py", line 31, in test_home_welcome_return
self.assertIn(u"Welcome to Reel!", response.data)
File "/usr/local/lib/python3.6/unittest/case.py", line 1077, in assertIn
if member not in container:
TypeError: a bytes-like object is required, not 'str'
我对回家路线的测试:
# Test Suite
import unittest
from reel import app
from reel.views import home_welcome
class HomePageTesttClass(unittest.TestCase):
@classmethod
def setupClass(cls):
pass
@classmethod
def tearDownClass(cls):
pass
def setUp(self):
self.app = app.test_client()
self.app.testing = True
def test_homepage_response(self):
result = self.app.get('/')
self.assertEqual(result.status_code, 200)
self.assertIn(b"Welcome to Reel!", result.data)
def tearDown(self):
pass
if __name__ == '__main__':
unittest.main()
我的意见档案:
from reel import app
from flask import render_template
@app.route('/')
def home_welcome():
return render_template("homepage.html")
@app.route('/signup')
def signup_welcome():
return 'Welcome to the signup page!'
@app.route('/login')
def login_welcome():
return 'Welcome to the login page!'
@app.route('/become_a_guide')
def guide_welcome():
return 'Welcome to the guide page!'
@app.route('/help')
def help_welcome():
return 'Welcome to the help page!'
我使用的一些资源来解决这个问题,这让我转向使用 b:
https://github.com/mjhea0/flaskr-tdd#first-test
What does the 'b' character do in front of a string literal?
感谢这是一个很长的问题,我试图提供尽可能多的上下文,因为老实说我觉得这个问题很愚蠢,但我不想在不知道为什么我使用的解决方案有效的情况下继续.
一如既往的感谢。
非常简短的简单答案是,字符串属于 str
类型 ,而 "b" 在 字符串前面 现在将使它成为一个 bytes 对象,属于 type
bytes。因此,期望是 yes 实际上它们应该 not 因为比较 different[=45] =] 类型预计会失败。
此外,您使用 assertIn
的断言是使用 in
关键字进行测试。在这种情况下,为了使用 in
进行正确测试,您 需要 将字节与字节进行比较。
观察这个简单的例子,它会引导您复制您正在经历的事情:
>>> s = "this is a string"
>>> t = "this is another string"
>>> type(s) == type(t)
True
>>> sb = b"this is a string"
>>> type(sb) == type(s)
False
>>> s in sb
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'str'
因此,如您所见,"b" 实际上在这里起到了一个功能性的作用,它为您提供了一种不同类型的 "object"。
您可以也解码为字符串:
>>> res = sb.decode()
>>> type(res)
<class 'str'>
建议明确说明您的解码,但是:
>>> res = sb.decode('utf-8')
>>> type(res)
<class 'str'>
最后, 是关于 containment 测试 bytes
的更详细的解释。希望这有帮助。
我目前正在构建一个小型 Web 应用程序来提高我的技能,作为其中的一部分,我正在尝试全面采用最佳实践、测试、CI、架构良好、代码简洁等那个。在过去的几次工作中,我一直在努力对我的根路由进行测试,而不是通过路由函数 returning 一个字符串,我正在渲染一个模板,我已经让它工作了,但我不明白为什么会这样,这让我很困扰。
主要是 b 的使用,在我的断言字符串之前,我认为这与我呈现的不是字符串,而是 html 表示形式有关,类似于return 和 print 之间的区别,但我很朦胧,希望有人教我。
我要问的是test_homepage_response函数的第4行。以及它是如何运作的。特别是关于这个错误,我得到:
正在 return 编辑的错误:
ERROR: test_home_welcome_return (tests.home_page_tests.HomePageTestClass)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/xibalba/code/reel/tests/home_page_tests.py", line 31, in test_home_welcome_return
self.assertIn(u"Welcome to Reel!", response.data)
File "/usr/local/lib/python3.6/unittest/case.py", line 1077, in assertIn
if member not in container:
TypeError: a bytes-like object is required, not 'str'
我对回家路线的测试:
# Test Suite
import unittest
from reel import app
from reel.views import home_welcome
class HomePageTesttClass(unittest.TestCase):
@classmethod
def setupClass(cls):
pass
@classmethod
def tearDownClass(cls):
pass
def setUp(self):
self.app = app.test_client()
self.app.testing = True
def test_homepage_response(self):
result = self.app.get('/')
self.assertEqual(result.status_code, 200)
self.assertIn(b"Welcome to Reel!", result.data)
def tearDown(self):
pass
if __name__ == '__main__':
unittest.main()
我的意见档案:
from reel import app
from flask import render_template
@app.route('/')
def home_welcome():
return render_template("homepage.html")
@app.route('/signup')
def signup_welcome():
return 'Welcome to the signup page!'
@app.route('/login')
def login_welcome():
return 'Welcome to the login page!'
@app.route('/become_a_guide')
def guide_welcome():
return 'Welcome to the guide page!'
@app.route('/help')
def help_welcome():
return 'Welcome to the help page!'
我使用的一些资源来解决这个问题,这让我转向使用 b:
https://github.com/mjhea0/flaskr-tdd#first-test
What does the 'b' character do in front of a string literal?
感谢这是一个很长的问题,我试图提供尽可能多的上下文,因为老实说我觉得这个问题很愚蠢,但我不想在不知道为什么我使用的解决方案有效的情况下继续.
一如既往的感谢。
非常简短的简单答案是,字符串属于 str
类型 ,而 "b" 在 字符串前面 现在将使它成为一个 bytes 对象,属于 type
bytes。因此,期望是 yes 实际上它们应该 not 因为比较 different[=45] =] 类型预计会失败。
此外,您使用 assertIn
的断言是使用 in
关键字进行测试。在这种情况下,为了使用 in
进行正确测试,您 需要 将字节与字节进行比较。
观察这个简单的例子,它会引导您复制您正在经历的事情:
>>> s = "this is a string"
>>> t = "this is another string"
>>> type(s) == type(t)
True
>>> sb = b"this is a string"
>>> type(sb) == type(s)
False
>>> s in sb
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'str'
因此,如您所见,"b" 实际上在这里起到了一个功能性的作用,它为您提供了一种不同类型的 "object"。
您可以也解码为字符串:
>>> res = sb.decode()
>>> type(res)
<class 'str'>
建议明确说明您的解码,但是:
>>> res = sb.decode('utf-8')
>>> type(res)
<class 'str'>
最后,bytes
的更详细的解释。希望这有帮助。