Python Code Coverage
Python は、現在最も人気のあるプログラミング言語の 1 つです。 その汎用的な性質により、Python は単純なスクリプトから Web サーバー、Django のようなフレームワークまで、さまざまなソフトウェア開発のユースケースで応用されています。
しかしながら、他のプログラミング言語と同様に、テストは Python におけるソフトウェア開発で最も重要な側面の 1 つであり続けています。
この投稿では、Python コードのテストケースカバレッジを測定して記述するためのいくつかのツールを紹介します。
Unittest
Python 標準ライブラリは unittest という名前のモジュールであらかじめ構築されています。 JUnit や主要なプログラミング言語の他のユニット テスト フレームワークに触発されて、unittest はテストの自動化、テストのための共有セットアップとシャットダウン コードなどを可能にするテスト フレームワークです。
unittest の重要な機能の 1 つはテストフィクスチャ、すなわち、1 つまたは複数のテストの実行に必要な設定、および関連するすべてのクリーンアップ動作です。 テキストフィクスチャを使用すると、一時的またはプロキシのデータベースやディレクトリを作成したり、サーバープロセスを開始したりするなどのアクティビティを 1 か所で処理することができます。
いくつかのサンプル テストケースを取り上げ、それらがどのように unittest を使用して実装されるかを見てみましょう。TestCase):
def test_upper(self):
self.assertEqual(‘foo’.upper(), ‘FOO’)
def test_isupper(self):
self.Test_isupper(self):
def test_upper(self):
self.assertEqual(‘foo’.upper(), ‘FOO’)assertTrue(‘FOO’.isupper())
self.assertFalse(‘Foo’.isupper())
def test_split(self):
s = ‘hello world’
self.assertEqual(s.split(), )
# check that s.Foo’.supper(self);
def test_small(self):# test_small(self);
self.self.self.isupper();def test_small(self);with self.assertRaises(TypeError):
s.split(2)
if __name__ == ‘__main__’:
unittest.main()
unittest.TestCase をサブクラス化してテストケースを作成します。 その後、メソッドを使用して個々のテストを定義できます。 テストケースの名前は単語 test で始めなければならないことに注意してください。 この命名規則により、どのメソッドがテストを表しているかがテスト ランナーに通知されます。
テスト ランナーは、テストの実行を編成し、結果をユーザーに提供するコンポーネントです。 その実装はさまざまで、グラフィカルインターフェース、テキストインターフェース、またはテストの実行結果を示す特別な値を返すかもしれません。 テストを作成するためのすべてのオーバーヘッドを削除することによって、効率的にあなたのテストを書くためのフレームワークを提供することを目的としています。 Pytest は Python 2.7, 3.4, 3.5, 3.6, Jython, PyPy-2.3 (Unix/Posix および Windows) でサポートされています。
Pytest を使い始める方法を見てみましょう。
インストールされたバージョンを確認するには、
それでは、サンプル関数と関連するテストケースを取り上げてみましょう。
def func(x):
return x + 1def test_answer():
assert func(3) == 5
関数funcは入力xを受けて値x + 1を返します。 このテストケースでは、関数funcが入力3を取り、5を返すかどうかをアサートしています。 このテストケースは失敗することが予想されます。 テストを実行するには test_sample.py.
$ pytest
================= テストセッション開始 =======================
platform linux – Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 itemtest_sample.py F =========================================== FAILURES ===========================
___________________________ test_answer ______________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_sample.py:5: AssertionError
=============== 1 failed in 0.12 seconds =================
Coverage.py
Coverage.py は Python で最も人気のあるコードカバレッジツールの 1 つです。 Python の標準ライブラリで提供されているコード解析ツールやトレースフックを使ってカバレッジを測定します。 CPython, PyPy, Jython と IronPython の主要なバージョンで動作します。 Coverage.py は unittest と Pytest の両方で使用できます。
最新版の Coverage をダウンロードして手動でインストールするか、次のように pip でインストールできます:
次に、あなたのプログラムを coverage で実行します:
Coverage の最新バージョンをダウンロードしてインストールするか、次のようにして pip でインストールできます。py arg1 arg2
次にカバレッジデータを取得するために
以下はカバレッジデータの出力例です
Name Stmts Miss Cover Missing
——————-
my_program.Of.Cover
My_Program.Of.Cover
My_Program.Of.Cover
My_Program.Of.Cover
my_other_module.py 56 6 89% 17-23
——————-
TOTAL 76 10 87%
HTMLファイルでレポートを生成する:
$ coverage html
これは Coverage.py によって作られる HTMLレポートの見本です。 モジュール、ステートメント、欠落、除外、ブランチ、パーシャル、カバレッジが含まれています。
Pytest-cov
Pytest-cov はカバレッジレポートを生成するための Python プラグインです。 coverage コマンドでサポートされる機能に加えて、集中テストと分散テストをサポートします。
一度 Pytest で必要なテストケースを書いたら、Pytest-cov を使ってすべてのテストを実行し、カバレッジを報告できます。
始めるには、次のように Pytest-cov をインストールします:
Centralised testing
Centralisedテストの報告対象はメインプロセスとそのすべてのサブプロセスの結合したものです。
Distributed testing
分散システムサポートのために Pytest-xdist をインストールします:
Distributed testing にはロードと各ディストに設定した2つのモードがあります。 loadに設定すると、分散テスト中にすべてのスレーブの合計カバレッジが報告されます。 スレーブは任意の数のホストに分散させることができ、各スレーブはファイルシステム上の任意の場所に配置することができます。 各スレーブは、そのサブプロセスを測定します。
各モードでの分散テストでは、pytest-cov はすべてのスレーブの結合されたカバレッジも報告します。 各スレーブがすべてのテストを実行しているので、これは複数の環境に対して結合されたカバレッジレポートを生成することを可能にします
まとめ
この投稿では、さまざまな Python ユニットテストとコードカバレッジフレームワークについて学びました。 これらのフレームワークはテストプロセスを簡単にしますが、それでもあなたはテストを書く必要があります。
- Use long, descriptive names.ここでは、ユニットテストを書いている間に考慮すべきいくつかのベストプラクティスを紹介します。 これは、しばしばテストメソッドの教義を不要にします。
- テストは分離されるべきです。 実際のデータベースやネットワークと相互作用しないようにしてください。 5040>
- Focus on one tiny bit of functionality.
- Should be fast, but a slow test is better than no test.
- It often makes sense to have one test case class for a single class or model.
This often makes sense for one test case class for a single class or model.
#3514>Short for test database for a individual test database which gets torn down or using mock objects. #3514