LoginSignup
12
7

More than 1 year has passed since last update.

VS CodeでPythonの単体テストをしてみよう

Posted at

はじめに

Visual Studio Codeにて、Python単体テストを試します。
参考にしたのは、公式のドキュメントです。

unittestとは

VS CodeのPython拡張にあらかじめ組み込まれているunittestを使用しました。

まずはunittestの基本的な考え方をおさらいします。

たとえば、引数aと引数bを加算する関数があったとします。

def add(a, b):
    return a+b

この関数に期待するのは、以下のような結果です。
(これは、関数の動作の正しさを保証するために、三通りのシナリオを用意したということですね)

  • add(1,3) → 4
  • add(0,0) → 0
  • add(-1,3) → 2

一つ目のシナリオについて、動作を確認するためのテストコードを書いてみます。
※実際にunittestで使用するコードではないので、ご注意を。

resualt = add(1,3)
if result == 4:
    print('OK')
else:
    print('NG')

今後、関数内部のコードを変更しても、このテストコードを走らせて正しい結果が出れば、関数が正しく動いていることを確認することができます。

そればかりでなく、さまざまなクラスやメソッドが複雑怪奇に絡み合い、コード変更の影響範囲がよくわからない場合でも、種々のテストコードにパスさえすれば、健全性が担保されます。問題が出たら出たで、大歓迎。考慮漏れを一つ潰して、コードの精度があがっていきます。

実際には、こうしたシナリオ(に基づいたテストコード)は、何十、何百と必要になってきますが、書くのも大変なら、実行するのも面倒くさいです。

そこで、テストコードを簡潔に書くことができ、ワンタッチで実行できれば、どんなにか便利なことでしょうか。

VS Codeでは、その仕組が提供されています。

準備

今回は、UNITTESTという名前のワークスペースを作りました。
テスト対象のファイルは、add.pyとし、コードを記入します。

add.py
def add(a, b):
    return a+b

テスト用のフォルダを作る

ワークスペースの中に、testsというフォルダを作りました。
テストコードは、この中に格納していくことになります。
VS Codeのエクスプローラーの「新しいフォルダ」ボタンを使ってもいいですし、普通にファインダー(エクスプローラー)を使っても構いません。

テストの設定をする

ここがちょっと独特の手順となりますが、コマンドパレットを使って、セットアップします。

command + shift + p (OSX)
ctrl + shift + p (windows)

でコマンドパレットを表示させ、

python test

等と入力します。
候補として、
Python:Configure Tests
が、現れますので、それを選択します。

表示が切り替わり、次はテストの種類の選択です。
pytestも候補で提案されていますが、今はunittestをお試ししたいので、Unittest Standard Python test frameworkを選択します。

今度はテスト用のフォルダの指定です。
先ほど作成した「tests」フォルダが選択肢にありますので、それを選びましょう。

最後に、テスト用ファイルの命名ルールを選択します。このルールに従った名前を持つファイルを見つけると、VS Codeはそれをテスト用ファイルとみなしてくれます。

ここでは、標準的であろう(たぶん)test_*.pyを選びました。

以上で、セットアップは完了です。
設定ファイルやフォルダが、自動的に作られています。

テストコードを書く

testsフォルダの直下に、test_add.pyというファイルを作成します。前段で、テスト用ファイルの命名ルールにtest_*.pyを選択しましたので、ファイル名はそれに従わなければなりません。

作成したファイルに、テストコードを書いていきます。

test_add.py
import unittest  # 標準モジュールを読み込みます
import add       # テスト対象のファイルを読み込みます

class TestA(unittest.TestCase):  # クラスを派生させて自分用のクラスを作ります
    def test_1(self):
        self.assertEqual(add.add(1, 2), 3)     # シナリオ1
        self.assertEqual(add.add(0, 0), 0)     # シナリオ2
        self.assertEqual(add.add(-1, -2), -3)  # シナリオ3

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

unittestの使い方としては、標準のunittest モジュールをインポートし、unittest.TestCase からテストクラスを派生させます。
まあ、僕は毎回、これをコピペです。
注目すべきは、

テスト対象のファイルをインポートしておくことと、

import add

あとは、テストクラス内で、テストのシナリオを書いていることですね。
実際にテストをするときは、これを書き書きしていくわけです。

self.assertEqual(add.add(1, 2), 3)
self.assertEqual(add.add(0, 0), 0)
self.assertEqual(add.add(-1, -2), -3)

self.assertEqual(A, B)というメソッドは、引数Aと引数Bの値が等しいことを検査するメソッドになります。

最後の記述は、テストファイル単体で実行するときに必要なものですので、今はなくてもいいですが、あっても困りません。

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

さあ、テストコードを書いたら(コピペしたら)、サイドバーにあるフラスコの形をした「テスト中」アイコン(変な名前だ)をクリックして、テスト中表示に切り替えてください。

設定した命名ルールに従ってテストファイルを作っていれば(かつテストコードに問題がなければ)、上図のように、作成したテストファイルやクラス、メソッドが表示されているはずです。

もし表示されていなければ、リロードボタンを押してください。

テストの実行

テスト中表示にすると、ファイルやクラス、メソッドのとなりに、右向きの白三角形アイコンが表示されています。

これをクリックすると、テストが実行されます。
メソッドごと、クラスごと、ファイルごとに実行できるので、便利ですね。

サイドバーに、

 「○個中○個のテストが成功しました(100%)」

と表示がでれば、成功です。
2-10.png
せっかくですので、テストに失敗するケースも見ておきましょうか。
三つ目のシナリオ、

self.assertEqual(add.add(-1, -2), -3)

は、-3という結果がでることを期待していますが、0を正解とするように修正しています。

self.assertEqual(add.add(-1, -2), 0)

この状態でテストを実行すると、「0じゃなくて、-3という結果が出たぞ」と警告してくれます。なかなか詳しいですね。
2-11.png
ちょっと手を加えて、assertNotEqual()(等しくない検査)にすれば、テストにパスします。

self.assertNotEqual(add.add(-1, -2), 0)

以上で、unittestの設定は完了です!

この先

必要最小限なことにしぼって、説明と設定を行いましたが、もちろん他にも様々な機能が準備されています。

・数々のアサートメソッド
作例では、値が等しいことを検査するself.assertEqualというメソッドを使いましたが、検査用メソッドは、他にもいろいろあります。

下記のアサートメソッド一覧は、参照する頻度が高いものでしょう。

アサートメソッド一覧(Python公式)

・setUp()、tearDown()
テストの実行に先立って、あらかじめ実行しておきたい処理があることがあります。
例えばCSVファイルを開いたり、DBにアクセスしたり、WEBサイトの中身を取得したり。

そんなときには、setupメソッドを使います。事後処理に使うのは、tearDownメソッドです。

セットアップ系メソッド

・例外処理
例外処理を絡めたテストをしたいという需要もあるかと思います。
assertRaisesなどのメソッドを使用します。

アサート系メソッド

以上です。

12
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7