小ネタです。
Python標準の単体テストツールunittestですが、テスト対象メソッドが例外を送出するかテストすることもできます。
その方法が他の言語とはちょっと違ったので、書いてみます。
バージョン
| 対象 | バージョン |
|---|---|
| OS | Windows 10 Pro 64bit |
| Python | 3.7.0 |
| Visual Studio Code | 1.27.2 |
| Python(拡張機能) | 2018.8.0 |
テスト対象メソッド
簡単なコードを書きました。
- テスト対象(
bases.filesモジュール)
from os import path import shutil def copy(source: str, destination: str): """destination で指定したディレクトリに、ファイルをコピーします。""" if not path.exists(source): raise FileNotFoundError(source + " is not found.") if not path.exists(destination): raise NotADirectoryError() if not path.isdir(destination): raise NotADirectoryError() shutil.copy(source, destination)
destinationで指定したフォルダに、ファイルをコピーするだけのものです。
例外発生の検知
次はテストコードです。
まず、ご作法通り、unittestを継承したクラスを作成します。
そして、テストメソッド内で
import unittest as ut import bases.files as f class test_copy(ut.TestCase): def test_notexist_file(self): with self.assertRaises(FileNotFoundError): f.copy("aaa", "bbb")
のように書きます。
with self.assertRaises(FileNotFoundError): f.copy("aaa", "bbb")
の部分がテストです。
- 例外発生部分を、
with句とともにassertRaisesで括る - 発生を期待する例外は、
assertRaisesに渡す with句の中で例外を発生させる処理を呼び出す
の3点が必要です。
メッセージをテストする
あまり需要は無いと思いますが、例外が送出するメッセージもテストできます。
assertRaisesの戻り値を取得すると、その中にメッセージが入っているようです。
with self.assertRaises(FileNotFoundError) as er: f.copy("aaa", "bbb") raise_except = er.exception self.assertEqual(raise_except.args[0], "aaa is not found.")
デバッグしてargs[0]の中にメッセージが入っているのを確認しましたが、もっと良い方法があるかもしれません。
ほかにも、エラーコードを確認したりできるようです。
テストコード全文
import unittest as ut import bases.files as f class TestCopy(ut.TestCase): def test_notexist_file(self): with self.assertRaises(FileNotFoundError) as er: f.copy("aaa", "bbb") raise_except = er.exception self.assertEqual(raise_except.args[0], "aaa is not found.")
下記のように、テストには成功しています。フォルダ階層等は環境に依存します。

おわりに
たしか、C#の場合、テストメソッドに属性を付ける、という方法でテストできたと思います。
言語によって流儀は違いますが、テスト手段が用意されているので、自分でtry - exceptするような書き方はしないように注意したいです。