実践・中級問題チェック
問題 35 /40
次のnormalize_name()関数をdoctestでテストする場合、★★★に入れる正しい記述はどれか。
normalize.py
-------------------------------
def normalize_name(name):
return name.strip().lower()
★★★
-------------------------------
選択 1
"""
名前文字列を正規化する関数です
>>> normalize_name(' Tanaka ')
'tanaka'
>>> normalize_name(' SUZUKI')
'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.testfile('normalize.txt')
選択 2
"""
名前文字列を正規化する関数です
normalize_name(' Tanaka ') => 'tanaka'
normalize_name(' SUZUKI') => 'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.testmod()
選択 3
"""
名前文字列を正規化する関数です
>>> normalize_name(' Tanaka ')
'tanaka'
>>> normalize_name(' SUZUKI')
'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.testmod()
選択 4
"""
名前文字列を正規化する関数です
>>> normalize_name(' Tanaka ')
'tanaka'
>>> normalize_name(' SUZUKI')
'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.run()
解説
選択肢3が正解です。
問題文のnormalize_name()関数は、前後の空白を削除して、大文字を小文字に変換する関数です。
def normalize_name(name):
return name.strip().lower()
これをdoctestでテストします。
【選択肢1】
"""
名前文字列を正規化する関数です
>>> normalize_name(' Tanaka ')
'tanaka'
>>> normalize_name(' SUZUKI')
'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.testfile('normalize.txt')
誤った記述です。
最後のtestfile()は、外部のテキストファイルに書かれたdoctestを実行するための関数です。モジュール内のdocstringのテストは、testfile()ではなくtestmod()を使います。
【選択肢2】
"""
名前文字列を正規化する関数です
normalize_name(' Tanaka ') => 'tanaka'
normalize_name(' SUZUKI') => 'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.testmod()
誤った記述です。
関数呼び出しと期待値の間で「=>」を使っています。doctestは「>>>」に続けて関数呼び出しを記述し、その下に期待値を記述します。
【選択肢3】
"""
名前文字列を正規化する関数です
>>> normalize_name(' Tanaka ')
'tanaka'
>>> normalize_name(' SUZUKI')
'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.testmod()
正しい記述です。
「>>>」に続く関数呼び出しの下に期待値を記述し、testmod()でモジュール内のdocstringテストを実行しています。
次のnormalize.pyをテストをする場合は、コマンドラインで「python normalize.py」と入力して実行します。
normalize.py
-------------------------------
def normalize_name(name):
return name.strip().lower()
"""
名前文字列を正規化する関数です
>>> normalize_name(' Tanaka ')
'tanaka'
>>> normalize_name(' SUZUKI')
'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.testmod()
-------------------------------
"""で囲むdocstringは、このように関数の外に書くか、def normalize_name(name):の直下に書きます。
実行すると、Pythonが変数__name__に__main__を代入し、if __name__ == '__main__':がTrueになり、doctest.testmod()が実行されます。
テストが成功すると、コマンドラインには何も表示されません。
doctest.testmod()を、doctest.testmod(verbose=True)とすれば、次のような詳細が表示されます。
Trying:
normalize_name(' Tanaka ')
Expecting:
'tanaka'
ok
Trying:
normalize_name(' SUZUKI')
Expecting:
'suzuki'
ok
1 items had no tests:
__main__
1 items passed all tests:
2 tests in __main__.normalize_name
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
docstringに、次のような誤った期待値を記述していた場合は、詳細が表示されます。
>>> normalize_name(' Tanaka ')
'tanakA'
◾️ verbose=Trueなし
*************************************
File "normalize.py", line 5, in __main__.normalize_name
Failed example:
normalize_name(' Tanaka ')
Expected:
'tanakA'
Got:
'tanaka'
*************************************
1 items had failures:
1 of 2 in __main__.normalize_name
***Test Failed*** 1 failures.
◾️ verbose=Trueあり
Trying:
normalize_name(' Tanaka ')
Expecting:
'tanakA'
*************************************
File "__main__", line 5, in __main__.normalize_name
Failed example:
normalize_name(' Tanaka ')
Expected:
'tanakA'
Got:
'tanaka'
Trying:
normalize_name(' SUZUKI')
Expecting:
'suzuki'
ok
1 items had no tests:
__main__
*************************************
1 items had failures:
1 of 2 in __main__.normalize_name
2 tests in 2 items.
1 passed and 1 failed.
***Test Failed*** 1 failures.
【選択肢4】
"""
名前文字列を正規化する関数です
>>> normalize_name(' Tanaka ')
'tanaka'
>>> normalize_name(' SUZUKI')
'suzuki'
"""
if __name__ == '__main__':
import doctest
doctest.run()
誤った記述です。
最後でdoctest.run()を使っていますが、doctestモジュールにrun()という関数は存在しません。
(公式書籍 p.366-367)