この記事で分かること

・Pythonテストコード「unittest」「pytest」の違い
・「pytest」導入方法

本記事では、これからPythonのテストフレームワークを使用する人向けに、Pythonの2つのテストフレームワーク「unittest」と「pytest」の違いや実際の活用法について、現場で実感したところをお伝えします。


目次

  1. Pythonのテストフレームワーク
  2. unittestについて
  3. pytestについて
  4. unittestを実際に書いてみる
  5. pytestを実際に書いてみる
  6. unittestとpytestの比較

1.Pythonのテストフレームワーク

Pythonのテストフレームワークは主に3つあります。

  • unittest
  • pytest
  • nose

今回は、標準フレームワークであるunittestと主流となっているフレームワークのpytest について比較していきたいと思います。

2.unittestについて

Pythonの標準モジュールで提供されているフレームワークです。
テストの自動化・初期設定と終了処理の共有・テストの分類・テスト実行と結果レポートの分離などの機能が提供されており、クラスを使って簡単にテスト開発することができます。

3.pytestについて

pytestはunittestやnoseの上位互換なツールとなっています。
unittestで書かれたテストをpytestでも実行できるため、unittestをすでに使用しているプロジェクトにも導入が容易です。
更に、unittestやnoseに比べて書き方がシンプルで、pythonらしい書き方でテストを書くことができます。

4.unittestを実際に書いてみる

unittestについてテスト用のプログラムを作成し、テストコードを書いてみます。

まず、テスト用の簡単なプログラムを用意しました。
それぞれ足し算引き算の簡単な計算を行うメソッドです。

この簡単なプログラムをテストするためのテストコードをunittestで書いてみます。

今回unittestの書き方としては以下となります。

・unittestをインポートする
・テストするファイルをインポートする
・各メソッドをテストするためのコードを書く

unittestの記法として以下の制約があります。

・テストケースをunittest.TestCaseのサブクラスとして作成
・メソッド名を「test_」で始める
・assertEqual()で予定の結果が得られていることを確かめる

assertEqual()内の第一引数に期待値、第二引数にテストするメソッドとメソッドの引数に計算する数値を記述します 。
以下コマンドで作成したテストコードを実行します。

テストコードを実行してみると、以下のような結果が取得できました。

sub_numの期待値として計算結果が9になる事を期待していましたが、実際の計算結果が1となってしまったため、テスト結果は「FAILED」 となっています。

メソッドの計算式を確認した結果、今回エラーとなっている原因は、テストケースの期待値が違っていたため、エラーとなってしまったsub_numのテストケースの期待値を「1」に修正します。

再度unittestを実行します。

全てのテストが実行され、sub_num()の計算結果が期待通り1となった事から全テストケース「OK」という結果が表示されました。
以降は同じテスト用プログラムを流用し、pytestで記述したテストコードを実行し、書き方の違いを確認していきます。

5.pytestを実際に書いてみる

unittestで使用したテスト用のプログラムを流用します。

プログラムをテストするためのテストコードをpytestで書いてみます。
今回のpytestの実施手順としては以下となります。

・テストするファイルをインポートする
・各メソッドをテストするためのコードを書く

pytestの記法として以下の制約があります。

・メソッド名を「test_」で始める
・assertで予定の結果が得られていることを確かめる

pytestのテストコードは以下イメージのような記述となります。

上記のunittestのテストコードは以下イメージのような記述となります。

unittestで行ったインポートやサブクラスとして作成の工程が無くなり、シンプルなテストコードとなりました。

以下コマンドで作成したテストコードを実行します。

テストコードを実行してみると、以下のような結果が取得できました。

sub_numの期待値として計算結果が9になる事を期待していましたが、実際の計算結果が1となってしまったため、テスト結果は「FAILED」 となっています。
実行したテストケース数に対して、passedとfailedの数が表示されているので、エラーとなっている箇所以外は通っている事が確認できて分かりやすくなっています。

メソッドの計算式を確認した結果、今回エラーとなっている原因は、テストケースの期待値が違っていたため、エラーとなってしまったsub_numのテストケースの期待値を「1」に修正します。

再度pytestを実行します。

全てのテストが実行され、sub_num()の計算結果が期待通り1となった事から全テストケース「OK」という結果が表示されました。

実際に書いてみると、期待値の書き方等は今回unittestではassertEqual()のみを使用していますが、期待値がTrueやFalseの場合はassertTrue()、assertFalse()を使用して記述するのに対し、pytestはassertで全て記述できる事などから、書き方が本当にシンプルで学習コストは比較的低いように感じました。

6.unittestとpytestの比較

 unittestpytest
インストールの有無標準モジュールのため必要なし必要
コードの記法他言語で標準として使用されているテストフレームワークに近い記法pythonらしい記法
テストの実行結果結果、及びテストが通らなかった箇所を表示ととてもシンプル結果、及びテスト失敗時に失敗箇所を詳細に表示

7.まとめ

unittestとpytestの違いを調べ、実際に簡単なコードを書いてテストを実行する事で両ツールの違いを実感しました。pytestはunittestの上位互換ツールであり、導入も容易でソースコードもシンプルな為、pytestのみ使用すれば良いと感じましたが、実際はunittestとの併用が発生しており、なぜ併用されるのかの疑問が残りました。
unittestを使用していたがpytestを後から導入したためunittestの記法で記述されている既存のテストケースをpytestの記法に修正できていないケース 、または併用する事でより複雑なテストを行う事が出来る様になる等、いくつか理由があると考えられます。

次回テーマはこの2つのフレームワークを併用する理由としたいと思います。