【Python】doctestでdictを扱う
課題
テストの自動化にdoctestは良いな、と思っていたらjsonのテストを行うとテストが通らない問題が発生した。
from datetime import datetime,timedelta import json def testFunc(test): """ >>> testFunc("Hello!") {"test":"Hello!"} """ return {"test":test}
Failed example: testFunc("Hello!") Expected: {"test":"Hello!"} Got: {'test': 'Hello!'} 1 items had no tests: test ********************************************************************** 1 items had failures: 1 of 1 in test.testFunc 1 tests in 2 items. 0 passed and 1 failed. ***Test Failed*** 1 failures.
解決方法
以下のようにすると良いらしい。
#method1 >>> sorted(testFunc("Hello!").items()) [("test","Hello!")]
又は
#method2 >>> testFunc("Hello!")== {"test":"Hello!"} True
なお、method2は期待する出力と関数内での出力の順番が異なっていても問題なくテストは通る
from datetime import datetime,timedelta import json def func(test): """ >>> testFunc("Hello!")=={"hello":"World","test":"Hello!"} True """ return { "test":test", "hello":"World" }
流石に改行を入れるとテストコードが通らないが、きちんとバックスラッシュ()を入れれば改行やインデントも入れられるため、可読性を上げられる。
#NG >>> testFunc("Hello!")=={ "test":"Hello!", "hello":"World" } True #OK >>> testFunc("Hello!")=={\ "test":"Hello!",\ "hello":"World"\ } True
#NG Failed example: testFunc("Hello!")=={ Exception raised: Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\doctest.py", line 1329, in __run compileflags, 1), test.globs) File "<doctest test.testFunc[0]>", line 1 testFunc("Hello!")=={ ^ SyntaxError: unexpected EOF while parsing 1 items had no tests: test ********************************************************************** 1 items had failures: 1 of 1 in test.testFunc 1 tests in 2 items. 0 passed and 1 failed. ***Test Failed*** 1 failures. #OK Trying: testFunc("Hello!")=={ "test":"Hello!", "hello":"World" } Expecting: True ok 1 items had no tests: test 1 items passed all tests: 1 tests in test.testFunc 1 tests in 2 items. 1 passed and 0 failed. Test passed.
原因
doctestはあくまで、出力が完全一致しているか確認するだけで、等価性のチェックは行わないらしい。 例えば、以下の値は並び順が異なるが本来は同じ値である。
#Example1 { "key":"Hello ", "value":"World" } #Example2 { "value":"World!", "key":"Hello " }
しかし、pytdocでのテストでは並び順が異るためエラーと認識される
どうやら、課題で挙げた問題はこの延長線上にあるようだ。
所感
doctestはドキュメントをコード内に書きながらテストコードを書けるため便利だが、大きなdictやlistが出力されるコードではunittestのほうが使い勝手が良いかもしれない。 ただ、現状はそこまで大きな出力を扱うコードを書く予定がないので、まずはdoctestでドキュメントを書きながらテストコードを充実させていくことを主眼に置きたい。