関数をテストしよう - assert編

【連載】

対話システムをつくろう! Python超入門

【第17回】関数をテストしよう - assert編

[2019/11/13 08:00]阿部憲幸 ブックマーク ブックマーク

開発ソフトウェア

前回は、モジュールに関数定義し、Pythonスクリプトからインポートすることで関数を再利用できるようにしました。今回は、テストとはそもそも何をすればいいのか考察した後、テストに用いるassert文を紹介します。

そもそも何をテストするのか

本連載では、現段階においてテスト用のプログラムは何も書いていないわけですが、今までは作成したプログラムが正しく動いているかどうかをどうやって判断していたでしょうか? そう、Pythonスクリプトを実行して、期待した値が表示されるかどうかを目視で確認することで判断していましたね。

例えば、前回実装した「main.py」が正しく動いているかどうかを確認するには、次のようにPythonスクリプトを実行し、その出力が期待した値と違いがないかどうかを確認していました。

$ python main.py
True
True

テストでは、今まで目視により確認していた「出力が期待した値と一致するかどうか」をプログラムで検証することになります。それにより、いつ誰が行っても同じ品質でプログラムの動作を検証できるようになるわけです。

さて、それではテストの対象となる「出力」とは一体何でしょうか? 目視で確認していた「出力」はPythonスクリプトの実行結果でしたが、より厳密に言えば確認していたのは「関数の戻り値」です。例えば、次のコードでは、match.check_match関数の戻り値を変数matched_fujiに束縛し、その値を表示しています。

patterns = ["富士山.*高さ", "東京.*区.*いくつ"]
text_fuji = "ねぇ、富士山の高さは?"
matched_fuji = match.check_match(patterns, text_fuji)
print(matched_fuji)

これはつまり、match.check_match関数の戻り値をチェックしていることにほかなりません。

ということは、今回のテストではmatch.check_match関数に引数を渡して実行し、その戻り値が期待する値かどうかをチェックすればいいわけですね。関数のように小さな単位でのテストは、プログラミングでは一般的に行われるもので「ユニットテスト」と呼ばれます。頭の片隅に留めておいてください。

assert文での判定

今回のテストでは、関数実行の戻り値が期待する値と等しいかどうかをチェックすればよいことがわかりました。Pythonでは、こうした確認に便利なassert文を提供しています。

assert文は、「assert」に続けてブール値を記述し、ブール値が「False」の場合のみエラーを表示してプログラムを終了します。なお、Pythonではプログラム実行中に発生するエラーを「例外」と呼びます。

このassert文がテストでどのように役立つのか見るために、次のような「assertion.py」というPythonスクリプトを作成してみましょう。

# assertion.py - assert 文の使い方
print("Check 1 == 1")
assert 1 == 1

print("Check 1 == 2")
assert 1 == 2

print("Check 1 == 3")
assert 1 == 3

このプログラムでは、2つの値「値1」と「値2」が一致しているかどうかを「==」演算子を使ってassert文で判定します。 assert文による判定の前には、判定を始めることを表すために「Check 値1 == 値2」のように比較する値を表示しています。

1つ目の判定「assert 1 == 1」では、「1」と「1」が同じ値であるかどうかを確認しています。当然、同じ値ですので「1 == 1」は「True」となり、assert文で例外は発生しません。一方で、2つ目の判定「assert 1 == 2」では「1 == 2」の判定結果は「False」となり、assert文で例外が発生します。

例外が発生した時点でプログラムは終了します。したがって、本来であれば3つ目の判定「assert 1 == 3」も例外が発生するのですが、2つ目の判定でプログラムが終了するため、3つ目のassert文は実行されないことになります。

それでは実際に実行して動作を確かめてみましょう。

$ python assertion.py
Check 1 == 1
Check 1 == 2
Traceback (most recent call last):
  File "assertion.py", line 6, in 
    assert 1 == 2
AssertionError

初めの2の判定が行われたことが「Check 1 == 1」「Check 1 == 2」が表示されていることからわかります。また、「Check 1 == 3」が表示されていないことから、プログラムは2つ目の判定の段階で終了し、3つ目のassert文は実行されていないこともわかります。

さて、「Traceback (most recent call last):」以降の出力は初めて見るものです。これは、Pythonが例外を発生して終了した時に表示する出力で「トレースバック」と呼ばれます。このトレースバックを読み解くことで、例外が発生したソースコードの箇所を特定することができるのです。

  File "assertion.py", line 6, in <module>
    assert 1 == 2

この記述では、「assertion.py」というファイルの6行目の「assert 1 == 2」で例外が発生したことを示しています。実行する前に予想していた例外発生箇所と一致するので、期待通りの動作をしていると言えるわけです。

今回は、モジュールに定義した関数が期待する動作をするか確かめるために何をテストすればいいのかについて確認した後、テストに用いるassert文を紹介しました。次回はいよいよ、このassert文を使ってテストを書いてみましょう。

著者紹介


株式会社NTTドコモ
R&Dイノベーション本部 サービスイノベーション部
阿部憲幸

2015年京都大学大学院理学研究科数学・数理解析専攻修了。 同年、NECに入社。 2016年から国立研究開発法人情報通信研究機構出向。 2018年より現職。 自然言語処理、特に対話システムの研究開発に従事。 毎日話したくなるAIを夢見て日夜コーディングに励む。
GitHub:https://github.com/noriyukipy

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

年間流通2000億円の「ふるさとチョイス」を1人で作った謙虚なエンジニアの偉勲

年間流通2000億円の「ふるさとチョイス」を1人で作った謙虚なエンジニアの偉勲

年間流通総額2000億円、月間PV約2億、関連自治体1500以上と、巨大なプラットフォームと化した日本最大級のふるさと納税サイト「ふるさとチョイス」。同サービスの基礎は、たった1人のエンジニアが作り上げた。現在、運営元のトラストバンクでシステム部の部長を務める高橋圭一郎氏だ。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で IT Search+ の人気記事をお届けします

会員登録(無料)

注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
[解説動画] 個人の業務効率化術 - 短時間集中はこうして作る
ミッションステートメント
教えてカナコさん! これならわかるAI入門
知りたい! カナコさん 皆で話そうAIのコト
対話システムをつくろう! Python超入門
Kubernetes入門
AWSで作るクラウドネイティブアプリケーションの基本
PowerShell Core入門
徹底研究! ハイブリッドクラウド
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

ページの先頭に戻る