初心者こそすぐにテストを実行せよ!Python+Unittest その2

初心者こそ、すぐにテストを実行せよ!Python + Unittestの第2回を書いていきたいと思います。

目標

この記事では、前回のテストコードより、ほんのちょっと応用を効かせてたコードを書けるようになりましょう。

  • 変数を使ったテストコードを書こう
  • 複数のテストコードを書こう
  • 指定したテストコードを実行してみよう

ぜひ、最後まで楽しく読んでいただけると嬉しいです。

対象者

  • Pythonのプログラミングをはじめた方
  • hello worldをプログラムで表示できる方
  • 勉強するなら、ほんの少しレベルの高いことを学びたい
  • 少しでもはやく、中級者の道へ進みたい方

おさらい

第1回目では、なぜテストコードが必要なのか?、どのような効果があるか?を簡単なサンプルを使って体験してもらいました。

# AとBが同じであれば、Trueを出力。違う場合は、Falseを出力
self.assertEqual(A, B)

テストコードは別の言葉で言うと、過去のあなたの分身です。

現在のあなたが過去のコードに影響する変更をしたとしても、あなたの分身がエラーを出してあなたに注意を促します。

初心者の頃は短いコードしか書かないかもしれませんが、テストコードを書く習慣を身につけていくことが大切ではないでしょうか。

まだ、第一回目を読んでない方は、

関連記事
●初心者こそすぐにテストを実行せよ!Python+Unittest その1

テストコードは、Unittestにお任せあれ!!

それでは、テストコードの書き方を見ていきましょう。

テストコードは、第1回で使ったUnittestを使います。
再度テンプレート(“sample.py”)を見てください。

#サンプルプログラム : Sample.py
# Unit testを使うことを宣言しまーす! 
# スポーツマンシップに則り、正々堂々戦う事を誓います! 高校野球じゃないよ ( ^∀^)
# 宣言するには、キーワードのimportを使います。
import unittest
class MyTest(unittest.TestCase):
    def test_XXX(self):
if __name__ == "__main__":
    unittest.main()

ルールはシンプルです!!

  • def test_XXX(self)のXXXのところにテストしたいコトを日本語で書
  • 一番はじめにエラーが出る事を確認する
  • Pythonコードを実行するコマンド + “ – v“をつける。

変数を使ったテストコードを書こう

前回、決まった値( 4 + 5とか、6 + 7とか)に対するテストができるようになりました。

今回は、変数を使って見ましょう!
変数は、数学で習ったxとかyとか数字の代わりに文字で表し、可変することができました。

前回の問題 4 + 5は、下記のようにも書くことができます。
x=4, y=5と変数を使って、簡単にかけると思います。

import unittest
class MyTest(unittest.TestCase):
    def test_変数Xたす変数Yは(self):
        x = 4
        y = 5
        期待値は = 9
        self.assertEqual(期待値は, x+y)
if __name__ == "__main__":
    unittest.main()

下記のような結果が出たかと思います。

まずは、失敗例 ( 4 + 4= 9 ? )
しっかり、エラーが出ているでしょうか?
一番最初にエラーが出ていることを確認するのが、一番大事です。

(base)  Tommy$  python3 sample.py -v
test_変数Xたす変数Yは (__main__.MyTest) ... FAIL
==============================================================
FAIL: test_変数Xたす変数Yは (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "sample.py", line 9, in test_変数Xたす変数Yは
    self.assertEqual(期待値は, x+y)
AssertionError: 9 != 8
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)

そして、成功例 ( 4 + 5 = 9 )

(base) Tommy$ python3 sample.py -v
test_変数Xたす変数Yは (__main__.MyTest) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK

複数のテストコードを書こう

今回は、関数を作ってみましょう。

関数とは、ある関連した処理を一つにまとめて、再利用できるようにする機能です。

イメージは、お風呂に子供を入れるという関数があったら、下記5つのことをすると定義します。そうすると、あなたは、奥様よりお風呂に子供を入れてと言われただけで作業できますよね。

  • 服を脱ぎます。
  • お湯を身体にかけます。
  • 身体を洗います。
  • 身体をタオルで拭きます。
  • 服を着ます。

プログラムも同じ考えだと思ってください。あらかじめ作業内容を決めておけば、プログラムは正確に実行してくれます。

関数は、def XXX():というタイトルで書きます。XXXのところに処理の名前を決めて書けばいいだけです。

すでにお気づきの方もいると思いますが、テストコードはそれぞれ関数として定義しています。あらかじめ定義した関数が、過去のあなたの分身となるんです。

今回は、三角形の面積を求める関数を作ってみましょう。
下記のコードを追加してください。

関数名が、area_of_triangle(三角形の面積)で、関数で使う変数がbase(底辺)とheight(高さ)です。

def area_of_triangle(base, height):
    return base * height / 2

全体のコードとしては、下記のようになります。
それでは、実行してみてくだださい。

import unittest
def area_of_triangle(base, height):
    return base * height / 2
class MyTest(unittest.TestCase):
    def test_変数Xたす変数Yは(self):
        x = 4
        y = 5
        期待値は = 9
        self.assertEqual(期待値は, x+y)
    def test_三角形の面積_底辺Xと高さY(self):
        x = 4
        y = 5
        期待値は = 10
        self.assertEqual(期待値は, area_of_triangle(x, y))
if __name__ == "__main__":
    unittest.main()

まずは、失敗例です。(底辺(X)が2,高さ(Y)が5の三角形の面積)

(base) Tommy$ python3 sample.py -v
test_変数Xたす変数Yは (__main__.MyTest) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
(base) Tommy$ python3 sample.py -v
test_三角形の面積_底辺Xと高さY (__main__.MyTest) ... FAIL
test_変数Xたす変数Yは (__main__.MyTest) ... ok
======================================================================
FAIL: test_三角形の面積_底辺Xと高さY (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "sample.py", line 20, in test_三角形の面積_底辺Xと高さY
    self.assertEqual(期待値は, area_of_triangle(x, y))
AssertionError: 10 != 5.0
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)

はい、三角形の面積の結果が期待通り間違っていますね。

あれ?Ran 2と書いてありますね。(Run(実行する)の過去形のRanです。)

実は、今まで実行してきた実行コマンドはtestで始まる関数を全て実行してくれます。そのため、一番はじめに書いたテストコードも実行されています。

まさしく、過去の過去のあなたがまだあなたのコードを見守ってくれています。

宿題

テストコードのすべての結果がOKになるように変更してください。

指定したテストコードを実行してみよう

最後の課題です。二つ目の課題で、関数を複数書けば、プログラムがすべてのテストコードを実行してくれました。

テストケースが膨大になると、実行する時間も比例して必要になります。

新しく書いたコードだけを念入りにテストした方が効率いいですよね。
そんな時は、プログラム実行時にテストしたい関数名を指定するだけで大丈夫です。

python3 -m unittest Sample.MyTest.test_三角形の面積_底辺Xと高さY -v

下記が結果です。指定したテストコードのみが実行されました。

(base) Tommy$ python3 -m unittest Sample.MyTest.test_三角形の面積_底辺Xと高さY -v
test_三角形の面積_底辺Xと高さY (Sample.MyTest) ... FAIL
==============================================================
FAIL: test_三角形の面積_底辺Xと高さY (Sample.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "Sample.py", line 20, in test_三角形の面積_底辺Xと高さY
    self.assertEqual(期待値は, area_of_triangle(x, y))
AssertionError: 10 != 5.0
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)

まとめ

この記事では、関数や変数を使って複数のテストコードを一気に実行させる方法を学びました。プログラム実行するコマンドを変更することによって、特定のテストコードのみを実行させることができます。

関連記事

関連記事
●初心者こそすぐにテストを実行せよ!Python+Unittest その3

●仕事の効率が劇的に改善する!UdemyのおすすめPython講座【感想あり】