16

I am working on some automated tests with a colleague and we wondered whether there were any differences in our approaches.

We have a method that returns a HTTP response object. Occasionally, it might return None, but normally an object.

The original code is:

self.assertTrue(response)

But I felt it might be more readable to have:

assert response is not None

I looked into the differences in the docs on truthyness, so I'm aware of things that would return true that aren't necessarily None. However, for the most part, both would work. And a lot of the existing tests are asserting true rather than asserting not none.

Is there any reason why one technique would work better than the other?

Craig Brett
  • 2,295
  • 1
  • 22
  • 27
  • 1
    My personal opinion is that `is not None` is more precise and should therefore preferred. I would not use `self.assertTrue` because this is just misleading. If you want a more "lazy" assertion, then use `assert response` instead. But this is just my personal opinion. – hek2mgl Nov 27 '19 at 10:09
  • Does this answer your question? [if A vs if A is not None:](https://stackoverflow.com/questions/7816363/if-a-vs-if-a-is-not-none) – Tim Nov 27 '19 at 10:55
  • @Tim: It's sort of related, though if it went with if A is true vs if A is not None. I know there's not a huge difference, or maybe there is – Craig Brett Nov 27 '19 at 11:28
  • I don't understand "though if it went with if A is true vs if A is not None" in your last comment. Actually *there is* a big difference, depending on what class is `response` from :) – Tim Nov 27 '19 at 13:03
  • Does my answer answers your question @CraigBrett? – Tim Nov 28 '19 at 09:01
  • I think so, yeah, and in lieu of any contradictory information, your answer ties in with my understanding of this. Thanks – Craig Brett Dec 04 '19 at 11:06

1 Answers1

24

tldr;

There is a functional difference in general, though in your particular case the execution result will be the same for both techniques. It now depends only on your willingness to be either explicit or concise.

Full answer

Assuming that a is a variable in Python, there is a difference between:

assert a

and

assert a is not None

In the fist case, you are evaluating the return of the call to the bool() buit-in on the object, which follows multiple strategies to get a result, as it was already discussed here.

This evaluates only according to the object's class implementation. Did you have a look on the class of your response object? It will tell you how bool(response) behaves.

In the second case, your are evaluating a as not being None. This is completely different. For example, an empty list will evaluate to False but is not None:

>>> a = []
>>> a is not None
True
>>> assert a is not None
>>> assert a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

If your response object is a sub-class derived from list, then it will probably behave the same way, so evaluating the emptiness of response is not equivalent to evaluating response as None.

In your case, I guess that your response object is provided by the request library. If so, then yes, in your particular case, both techniques are functionally equivalent, though you should notice a tiny performance gain evaluating against None.

Tim
  • 2,052
  • 21
  • 30