coLinux日記

coLinuxはフリーソフトを種として、よろずのシステムとぞなれりける。

SimplePrograms で Python を学ぶ その13

2024-05-24 22:29:16 | Python
SimplePrograms - Python Wiki
https://wiki.python.org/moin/SimplePrograms

の 13番目のプログラムは、 unittest を使った ユニットテスト です。

import unittest
def median(pool):
    copy = sorted(pool)
    size = len(copy)
    if size % 2 == 1:
       return copy[int((size - 1) / 2)]
    else:
       return (copy[int(size/2 - 1)] + copy[int(size/2)]) / 2
class TestMedian(unittest.TestCase):
    def testMedian(self):
       self.assertEqual(median([2, 9, 9, 7, 9, 2, 4, 5, 8]), 7)
if __name__ == '__main__':
    unittest.main()


13番目に出てくるということは、unittest って、 Python では有用なモジュールみたいですね。
しかも利用するためにクラスを使っているので、12番目がクラスだったのですね。

プログラムの見た目だけでは動きの想像が付かないので、例によってファイルにして実行してみます。

$ ./prog-013.py
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
$

マニュアル、
https://docs.python.org/ja/3/library/unittest.html#module-unittest
を参考に unittest を調べましょう。最も参考になるのは、
https://docs.python.org/ja/3/library/unittest.html#basic-example
の基本的な例の部分ですね。これと、13番目のプログラムを対比すると、関数 median()
の定義の後のクラス TestMedian の定義は、object の代わりに unittest.TestCase を指定してるので、
「テストケースは、 unittest.TestCase のサブクラスとして作成します。メソッド名が test で始まる三つのメソッドがテストです。」
から、

テストケース TestMedian は、unittest.TestCase のサブクラスとして作成され、
テストランナーは、TestMedian の メソッドで test で始まる、 メソッド testMedian を検索してテストするようです。

「これらのテスト内では、予定の結果が得られていることを確かめるために assertEqual() を、条件のチェックに assertTrue() や assertFalse() を、例外が発生する事を確認するために assertRaises() をそれぞれ呼び出しています。」
なので、
assertEqual() の、第一引数 media関数の実行結果が、第二引数となっているかどうかを確かめるテストを実施するようです。

「最後のブロックは簡単なテストの実行方法を示しています。 unittest.main() は、テストスクリプトのコマンドライン用インターフェースを提供します。コマンドラインから起動された場合、上記のスクリプトは以下のような結果を出力します」
なので、以下のテストの実施方法は丸ごと覚えるのが正解のようです。

if __name__ == '__main__':
    unittest.main()

それで、unittest によって、プログラムの実行結果のような結果が表示されるのですね。

ちなみに定義したmedian()関数は、

>>> a = len([1, 2, 3, 4, 5])
>>> a
5
>>> a % 2
1
>>> a % 2 == 1
True
>>> b = len([1, 2, 3, 4])
>>> b
4
>>> b % 2
0
>>> b % 2 == 1
False
>>>

なので、関数 median() に渡される引数として数字要素のリストを渡すと、
それを sorted() でソートして、len() でリストの要素数を求めて、
条件式 size % 2 == 1 ( % はあまりを求める算術演算子で、そのあまりが 1 に等しいどうかを調べる)から、
要素数が奇数の場合は真ん中の要素を return で返し、
要素数が偶数の場合は真ん中に近い2つの要素を2 で割った平均を return で返す、
関数であることが分かります。

unittest で、 testMedian というテストを作成し、median([2, 9, 9, 7, 9, 2, 4, 5, 8])
が正しく 7 を返すかどうかをテストするのですね。

こんな単純なテストでは分かりませんが、かなり複雑な関数を作成し、色々な引数での返却値が正しいかどうかのテストを
unittest で実施しておいて、
その後、関数に機能を追加したり、バグがあったりした場合、その結果を更に unittest のクラスのメソッドに追加していけば、
作成した unittest プログラムを実行するだけで修正が正しい事を保証できるレポートが手に入るので、
unittest の利用価値は高そうです。

Python を学んでいる者としては、Python でどのくらい unittest が利用されているか興味深いです。

コメント (2)    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« SimplePrograms で Python を... | トップ | SimplePrograms で Python を... »
最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
Pythonに於けるUnitTest (cametan_42)
2024-05-25 01:14:29
次のページも見てみて下さい。

Dive into Python3/ユニットテスト:
https://diveintopython3tojp.blogspot.com/2016/07/09-01.html
返信する
unittest は面白い (espiya)
2024-05-29 21:38:10
cametan_42 様、コメントありがとうございます。

ご紹介のドキュメントを見ると、
関数等を作るときに、先にテストを作成してから、その関数を作成してテストする、
というのがお勧めみたいですね。

ということは、学校とかの教室で、これからPython で作成する関数の仕様を説明して、「作成できたらこのテストを通して、クリアできるか調べてね」みたいな使い方もありそうですがどうでしょうか。
返信する

コメントを投稿

Python」カテゴリの最新記事