本連載は、毎回、いろいろなプログラミング言語のテストフレームワークを紹介します。いろいろなテストの書き方を知って、ソフトウェアの品質向上をさせましょう。1回目の今回は、プログラミング言語Pythonで最も人気のあるフレームワークpytestを紹介します。pytestはとても気軽に使えるので、職業プログラマーではない方にもオススメです。
pytestとは
今回取り上げる「pytest」はPythonで人気のテストフレームワークです。シンプルで直感的なのが特徴です。テスト用の関数を作るには「test_」から始まる名前の関数を定義するだけで良いので、既存のプログラムに手軽にテストを追加できます。
「pytest」のインストール
それでは、最初にプログラミングPythonに加えて「pytest」をインストールしましょう。Pythonのインストール方法はいろいろありますが、公式サイト(https://www.python.org/)からインストーラーをダウンロードしてインストールするのが簡単でしょう。
そして、「pytest」をインストールするには、OSのターミナル(WindowsならPowerShell、macOSならターミナル.app)を起動して、次のコマンドを実行します。
# Windowsの場合
pip install pytest
# macOSの場合
pip3 install pytest
「pytest」で一番簡単なテストを書いてみよう
そもそもPythonには標準で「unittest」と呼ばれるライブラリが含まれていますが、これはJavaのJUnitに影響を受けたフレームワークであり、クラスベースでテストを作る必要があります。しかし、「pytest」を使えば、テストを作るためにクラスを定義する必要はありません。「test_」から始まる関数を記述すれば良いのです。 ここでは、一番簡単なテストとして、足し算を行う関数add()を定義してみて、この関数が正しく実装されているかを確認するテストを書いてみましょう。
まずは、足し算を行う関数add()ですが、下記のように記述しました。
# 引数に与えたaとbを足して返す関数
def add(a, b):
return a + b
そして、この関数をpytestでテストする関数test_add()を定義します。次のように「assert (テスト内容)」のように記述します。
# 関数add()をテストする関数
def test_add():
assert add(2, 3) == 5
assert add(5, -3) == 2
assert add(100, 300) == 400
それでは、実際にテストしてみましょう。上記の関数add()とtest_add()は同じ一つのファイルに記述できます。ここでは、以下のような内容で「calc.py」というファイルに保存しましょう。
# ファイル名: calc.py
# 引数に与えたaとbを足して返す関数を定義
def add(a, b):
return a + b
# pytestで関数add()をテストする関数
def test_add():
assert add(2, 3) == 5
assert add(5, -3) == 2
assert add(100, 300) == 400
それでは、pytestでテストを実行してみましょう。pytestをインストールすると「pytest」というコマンドが利用可能になります。それで、ターミナルから次のコマンドを実行します。
pytest calc.py
すると、ターミナルの次のように表示されます。注目したいのは、実行結果の最終行です。「=== 1 passed in 0.00s ===」のように表示されます。これは、実行した1つのテストがすべて成功したことを表しています。
テストが失敗することを確認してみよう
なお、テストを書く場合、気をつけないといけないのが、「テストが正しく失敗してくれるか」どうかという点です。もし、作ったプログラムにバグがあったとして、それをテストで検出できないのでは、テストがないよりも悪いことになります。
ここでは、先ほど作成したファイル「calc.py」の内容を複製して、「calc_ng.py」を作成しましょう。そして、関数add()の内容を次のように書き換えてみましょう。これは、本来addは引数aとbを足す関数ですが、間違えてaとbを掛けてしまう関数を書いたものです。
# 敢えてバグのある関数に書き換えてみた
def add(a, b):
return a * b # わざと間違えている
それでは、テストが失敗するか確認してみましょう。
pytest calc_ng.py
すると次のように表示されます。画面に赤色が多く表示され、いかにもエラーがあるという感じになりました。
注目したいのは、やはり実行結果の末尾です。「=== 1 failed in 0.06s ===」と表示されて、1つのテストを実行したけれども、テストが失敗したということを表しています。
そして、少し上を見ると、「=== FAILURES ===」(失敗)とあり、赤字で「assert 6 == 5」と表示されます。これは、関数の実行結果が6になったが正しくは5であるという意味です。この部分に実際のassertの式も表示されるので、どのテストで失敗したのかが一目で分かります。
pytestの結果は英語で表示されるので、英語に苦手意識があると見たくないという気持ちになってしまいますが、エラーの見方さえ分かれば難しいことばありません。テストが失敗したこと、どこで失敗したのかが分かれば、プログラム修正の糸口を見つけることができます。
pytestを使う上で覚えるべきことは一つだけ
ここまで見たように、pytestを使う場合なら、プログラムの中に自然な形でテストを記述することができます。加えて、テスト専用のモジュールファイルを用意することで、テストを行うこともできます。この場合「test_(対象ファイル).py」のように、ファイル名に「test_」を加えます。