pythonpython-3.xunit-testingflasknose2

How to assert variable content in unit test (Flask, Python3, Nose2)


I have a Flask app where some page content comes from a global variable. I'm trying to set up some unit testing to assert the data, but I can't seem to get even a local variable to work:

TEST_STRING = foo

self.assertIn(b['TEST_STRING'], response.data)

fails with:

NameError: name 'b' is not defined

If I reference the plain variable:

self.assertIn(TEST_STRING, response.data)

I get the expected failure:

TypeError: a bytes-like object is required, not 'str'

The test succeeds if I hard-code the variable data into the test, but I'd rather not have to update the test if the variable changes. What am I missing here?


Solution

  • The problem was with the bytes literal prefix b:

    Bytes literals are always prefixed with 'b' or 'B'; they produce an instance of the bytes type instead of the str type. They may only contain ASCII characters; bytes with a numeric value of 128 or greater must be expressed with escapes.

    While it sounds like bytesprefix = bytes type, this does not seem to work if the data comes from a variable.

    The solution was to change the b prefix to the bytes functionbytes, which states:

    Bytes objects can also be created with literals, see String and Bytes literals.

    So while they appear interchangeable, this is not always the case!

    For my use case, I also had to specify my encoding type for the bytes function.

    Here is the working syntax to my original post's example:

    self.assertIn(bytes(TEST_STRING, "utf-8"), response.data)
    

    Thanks goes to John Gordon who suggested switching to bytes in the comments, but never officially answered. So after a few days, I'll go ahead and close this out now.