Flask Unit Testing and not understanding my fix for "TypeError: a bytes-like object is required, not 'str'"

Viewed 1439

I am currently building a small web application to improve my skills, as part of this, I am trying to go with best practices across the board, testing, CI, well architected, clean code, all of that. Over the last few sessions of working on it, I have been struggling with a test on my root route where instead of returning a string via the route function, I am rendering a template, I have gotten it to work, but I don't understanding why it works, and this bothers me.

Primarily, it's the use of the b, before my assertion string, I assume it is to do with the fact that what I am rendering is not a string, but a html representation, akin to the difference between return and print, but I am hazy and would appreciate for someone to school me.

The line I am asking about is line 4 of the test_homepage_response function. And how it operates. Especially in regards to this error I was getting:

The error being returned:

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'

My tests for the home route:


# 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()

My views file:


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!'

Some of the resources I used figuring this out, which pointed me towards the use of the b:

https://github.com/mjhea0/flaskr-tdd#first-test

What does the 'b' character do in front of a string literal?

Appreciate this is a long one, I tried to provide as much context because I honestly feel pretty stupid with this question, but I didn't want to just continue on without knowing why the solution I'm using is working.

Thank you as always.

1 Answers
Related