MyEnigma

とあるエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

PythonのデフォルトのUnitTestsではなくpytestを使うべき7つの理由

目次

はじめに

これまで、自分はPythonのユニットテストには、

PythonのデフォルトのUnitTestsを使っていましたが、

docs.python.org

myenigma.hatenablog.com

自分がコントリビュートしているPython OSSの殆どが

pytestというテストフレームを使っていたので、

気になって調べてみました。

docs.pytest.org

PythonのデフォルトのUnitTestsではなくpytestを使うべき7つの理由

下記は、これまでPythonデフォルトのUnitTestsを使ってきた自分が、

pytestを使ったほうが良いなと思った7つの項目です。

 

1. クラスを作らずにシンプルな関数でテスト関数を作ることができる。

UnitTestsはJavaのユニットテストフレームワークである

JUnitをベースとして開発されているため、

docs.python.org

テストを作成する時に毎回UnitTestsクラスを継承した

テストクラスを作成する必要があります。

 

一方、pytestの場合、クラスは作る必要がなく、

test_*.py または、*_test.pyというファイルに、

test_*という名前の関数をさえ作れば、

pytestが勝手にその関数を検索して、テストとして実行してくれます。

 

これにより、テストを書く敷居がかなり低くなり、

テストを書きやすくなると思います。

 

2. 様々なassert関数を覚えなくて良い

UnitTestのテストは、assertTrueやassertEqualなど、

様々なassert関数を使ってテストを作成しますが、

どのようなassert関数使うべきか覚える必要があります。

 

pytestでは、Pythonのデフォルトキーワードである

assert文を使って、条件を書くことによりテストを評価します。

これにより、すべてのテストコードを一貫性をもって、

作成することができると思います。

 

3. テストが失敗した理由がわかりやすい

UnitTestsで作成したテストが失敗した場合、

そのテストが失敗したことはわかりますが、

なぜそのテストが失敗したのかは、

テストの結果をみるだけではわかりにくいと思っていました。

 

一方、pytestの場合、

下記の公式ドキュメントにあるように

失敗したテストに関しては、

それぞれの値がどのような値であったせいで、

テストが失敗したのかをわかりやすく表示してくれます。

docs.pytest.org

 

加えて、コマンドライン引数で設定することにより、

テストが失敗したときに定義されていた

それぞれの変数の中身なども表示することができ、

再度テストを実行しなくても、

テストのログだけで、ある程度のデバックができるようになっています。

 

4. テストの検索と実行が高機能 (auto discovery)

UnitTestsにも、自動的にテストコードを検索して、実行する

auto discovery機能がありますが、

pytestにauto discoveryはより一層使いやすく、高機能だと思います。

 

例えば、

$ pytest

とタイプすることで自動的にcurrent directory以下のテストを検索してくれますが、

検索するディレクトリを指定したり、

あるテストファイルの一部のテストのみ実行したり、

テスト名の部分一致で検索して実行なども

すべてコマンドライン引数を設定することで可能です。

 

5. 様々なプラグインが公開されており、簡単に機能追加できる

pytestには、プラグイン機能があり、

様々な便利な追加機能のためのプラグインが公開されています。

 

例えば、

マルチスレッドや分散処理でテストを並列実行するpytest-xdistや

pypi.org

文法/コードスタイルチェッカーであるpyflakesを実行するpytest-flakes

github.com

コードカバレッジを確認するpytest-cov

pypi.org

などがあります。

これらのプラグインは、それぞれpipでインストールでき、

あとは必要な設定やデータをpytestのオプションに指定すれば

それぞれの機能を利用可能です。

 

6. UnitTestsで作成されたテストも実行できる

pytestは、Pythonのデフォルトのテストフレームワークである

unittestで作成されたテストも実行可能です。

docs.python.org

これにより、すでに沢山のUnitTestsベースのテストが存在している

プロジェクトにおいても、pytestで既存のテストを実行しつつ、

少しづつ、pytestのテストに置き換えていくことができます。

 

また、UnitTestsベースのテストが失敗したときも、

pytestで実行した場合、わかりやすく失敗した理由を表示してくれます。

 

7. テストの実行時間のランキングを簡単に作成してくれる

--duration=0というオプションを使うことにより、

簡単にテストの実行時間の遅いものからランキングリストを作ってくれます。

下記は自分のOSSの場合の出力例です:

f:id:meison_amsl:20210131212126p:plain

上記のように、簡単にどのテストが失敗しているのかわかり、

そのような遅いテストを改善したり、

テスト対象のコードそのものを改善することができます。

 

便利なコマンドライン引数表

コマンドライン引数 機能
-l トレースバックとともにローカル変数も表示
-v すべてのテスト名とその結果を表示
--lf 前回失敗したテストだけを実行
-x 最初の失敗したテストでテストを止める
-Werror Warningが出たときもエラーにする
--durations=N テスト実行時間がN秒以下のテストを表示(0に場合はすべて)

 

PythonのIDEとpytestの連携

JetbrainsのPython IDEであるPycharmは、

myenigma.hatenablog.com

テストフレームワークとして、pytestに対応しています。

下記の公式ドキュメントにある通り、

IDEからテストを実行し、テスト結果をわかりやすく表示したり、

auto discoveryでテストを検索することもできます。

pleiades.io

pleiades.io

 

参考資料

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

MyEnigma Supporters

もしこの記事が参考になり、

ブログをサポートしたいと思われた方は、

こちらからよろしくお願いします。

myenigma.hatenablog.com