読者です 読者をやめる 読者になる 読者になる

新・オノマトペ的備忘録

技術ブログだと思った? 残念、日記でした!

式が True / False そのものであるかどうかの Assert には assertIs(expr, boolean) を使う

おねがい

『何年 Python 使ってんだよ』『そんなんで仕事してたんかい』などといいながら棒状のもので叩くのはやめてください……言い訳をさせてもらうといままでだいたい文字列やバイト列の比較とかだったので assertEqual で事足りてたんです…….

本題

Django どんなもんだったかなって思い出したくてチュートリアル見直してた. Writing your first Django app, part 5 | Django documentation | Django で『False であるはず』の Assert に assertIs(expr, False) を使ってたんだけど,「あれ? assertFalse(expr) ってのもあった気がするけどこれじゃダメなの?」と思って調べてみた.

26.4. unittest — Unit testing framework — Python 3.5.2 documentation によると,assertTrue について

Note that this is equivalent to bool(expr) is True and not to expr is True (use assertIs(expr, True) for the latter).

とあったんだけど,bool(expr) is Trueexpr is True の違いについて数分本気で悩んでしまった.気づいてしまえばすごい単純なことだった(はずかし).次の実行例を見るとわかるんだけど,式が真(偽)と判定されるということと,式(の評価結果)が True (False) である,ということは等価ではない.

>>> if 1:
...  print('1 is treated as True')
...
1 is treated as True
>>> if 1 is True:
...  print('1 is True')
...
>>> if bool(1) is True:
...  print('bool(1) is True')
...
bool(1) is True

だから,exprFalse であるはず,というつもりで assertFalse(expr) という assert を置いても,実際は exprNone だったり 0 だったりしてもこの assert をパスしてしまう. assertIs(expr, False) なら exprFalse そのものであることが保証される.

まとめ

真であるか / 偽であるか,と True そのものであるか / False そのものであるか,は違うことなので,後者をチェックしたいなら assertIs(expr, boolean) を使うべき.