エンジニア

py.testのおすすめプラグイン

投稿日:2015年5月26日 更新日:

サーバーエンジニアの原です。

今回は、Python製テスティングフレームワークpy.testの数あるプラグインのうち、おすすめプラグインをご紹介します。

Python 3.4、pytest 2.7.0を前提とします。

pytest-flakes

pytest-flakesは、Pythonの文法/コードスタイルチェッカーであるpyflakesをテスト時に実行できるようになるプラグインです。

例えばこのような(全く役に立たない)テストコードがあったとします。

# -*- coding: utf-8 -*-

def test():
    a = 5
    assert 1+2 == 3

これを--flakesオプションを付けてテストを実行すると、未使用の変数があるため、テストが失敗します。

$ py.test --flakes
===================================== test session starts ==============================
platform darwin -- Python 3.4.2 -- py-1.4.27 -- pytest-2.7.1
rootdir: /Users/hara/work/pytest, inifile:
plugins: cache, flakes
collected 2 items

tests/test_app.py F.

========================================== FAILURES ====================================
_______________________________________ pyflakes-check _________________________________
/Users/hara/work/pytest/tests/test_app.py:5: UnusedVariable
local variable 'a' is assigned to but never used
============================= 1 failed, 1 passed in 0.02 seconds =======================

これにより、CIでコードスタイルもチェックできるようになります。

特定のスタイルチェックを無効化したり、特定のファイルのみにスタイルチェックを実行するなどの設定もできるので、プロジェクトの特性に応じて設定しておくとよいでしょう。

pytest-echo

pytest-echoは、テスト実行時に環境変数やパッケージのバージョンなどを出力するプラグインです。

以下のようなオプションを付けて実行すると、テスト結果に環境変数やパッケージのバージョンなどが含まれるようになります。

$ py.test --echo-env PWD --echo-version pip --echo-version pytest
================================= test session starts ==================================
platform darwin -- Python 3.4.2 -- py-1.4.27 -- pytest-2.7.1
Environment:
    PWD: /Users/hara/work/pytest
Package version:
    pip: 1.5.6
    pytest: 2.7.1
rootdir: /Users/hara/work/pytest, inifile:
plugins: cache, cov, echo, flakes
collected 1 items

tests/test_app.py .

=============================== 1 passed in 0.02 seconds ===============================

テスト実行環境の情報を出力しておくことで、テスト失敗時の原因追求がしやすくなります。
引数が多くなってしまう場合は、以下のようにpytest.iniのaddoptsに予めオプションを指定しておくと毎回オプションを指定する必要がなくなります。

addopts = --echo-env PWD
          --echo-version pip
          --echo-version pytest

pytest-cov

pytest-covは、テスト実行時にテストカバレッジを取得するプラグインです。

--covオプションの後ろには、カバレッジを取得する対象ディレクトリを指定します。

$ py.test tests --cov .
================================= test session starts ==================================
platform darwin -- Python 3.4.2 -- py-1.4.27 -- pytest-2.7.1
rootdir: /Users/hara/work/pytest/tests, inifile:
plugins: cache, cov, echo, flakes
collected 1 items

tests/test_app.py .
------------------- coverage: platform darwin, python 3.4.2-final-0 --------------------
Name             Stmts   Miss  Cover
------------------------------------
sample               2      2     0%
tests/test_app       3      0   100%
------------------------------------
TOTAL                5      2    60%

=============================== 1 passed in 0.03 seconds ===============================

テストの実行結果には影響を与えませんが、テストカバレッジを手軽に取得することができます。

pytest-describe

pytest-describeは、RSpecやJasmineのようなDescribeスタイルと呼ばれるテストコード記法をサポートするプラグインです。

py.testにはクラスを使用することで複数のテスト関数(メソッド)をまとめることができますが、そのクラスにはTestというプレフィックスを付けなければならなかったり、テスト関数(メソッド)ごとにselfを引数に取る必要があったりとスマートに記述することができませんでした。

pytest-describeを使用することで複数のテスト関数を関数でまとめることができるため、特別なルールなしに記述することが可能となっています。

以下に一例を載せます(READMEからの引用です)。

# -*- coding: utf-8 -*-  
import pytest

def describe_list():

    @pytest.fixture
    def list():
        return []

    def describe_append():

        def adds_to_end_of_list(list):
            list.append('foo')
            list.append('bar')
            assert list == ['foo', 'bar']

    def describe_remove():

        @pytest.fixture
        def list():
            return ['foo', 'bar']

        def removes_item_from_list(list):
            list.remove('foo')
            assert list == ['bar']

以下のようなテスト結果になります。

$ py.test -v
================================= test session starts ==================================
platform darwin -- Python 3.4.2 -- py-1.4.27 -- pytest-2.7.1 -- /Users/hara/.pyenv/versions/engineer_blog/bin/python3.4
cachedir: /Users/hara/work/pytest/.cache
rootdir: /Users/hara/work/pytest, inifile:
plugins: cache, cov, describe, echo, flakes
collected 2 items

tests/test_list.py::describe_list::describe_append::adds_to_end_of_list PASSED
tests/test_list.py::describe_list::describe_remove::removes_item_from_list PASSED

=============================== 2 passed in 0.02 seconds ===============================

describeというプレフィックスの関数が、テストをまとめる関数であることを表しています。


このプレフィックスは、pytest.iniにdescribe_prefixesという設定を追加することで自分の好きなように修正することができます。

まとめ

4点のpy.testプラグインをご紹介しました。

Pythonを初めとするLLの良さの一つとして、コンパイルという手順が無いことによるユニットテスト等のフィードバックループの回しやすさが挙げることができます。LLの力を最大限に活かし、より良いユニットテストを行なうためにも、テスト手法の改善に努めていきたいものです。

py.testには他にもプラグインがたくさんあります。こちらにプラグイン一覧がありますので、興味がある方は調べてみてください。

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-

© WonderPlanet Inc.