LoginSignup
43
56

More than 5 years have passed since last update.

Jenkinsさんにお世話になるPython開発 - ユニットテスト編

Last updated at Posted at 2016-06-11

本記事の概要

Pythonを用いた開発において、ユニットテストをJenkinsさんにやってもらう方法を解説する。
Pythonのユニットテストフレームワークとしては、noseかpy.testが候補になりますが
今回は、py.testを使います。

Jenkinsさんには、
* テストの自動実行
* テストレポートの出力
* カバレッジの出力と視覚化
をやってもらいます。

環境は以下の通り。

項目 バージョンなど
Python 3.5.1
Jenkins 1.6...?
テストフレームワーク py.test

py.test

pip install pytestでインストール

テストコードの例

テスト対象コード - calculator.py

class Calculator():
    def add(self, a, b):
        return a + b

    def sub(self, a, b):
        return a - b

    def mul(self, a, b):
        return a * b

    def div(self, a, b):
        return a / b

テストコード - test_calculator.py

import pytest
from calculator import Calculator

def pytest_funcarg__calc():
    return Calculator()

@pytest.mark.parametrize("a, b, r", [(9, 8, 17), (7, 6, 13), (5, 4, 9), (3, 2, 5), (1, 0, 1)])
def test_add(calc, a, b, r):
    assert calc.add(a, b) == r

@pytest.mark.parametrize("a, b, r", [(9, 8, 1), (7, 6, 1), (5, 4, 1), (3, 2, 1), (1, 0, 1)])
def test_sub(calc, a, b, r):
    assert calc.sub(a, b) == r

@pytest.mark.parametrize("a, b, r", [(9, 8, 72), (7, 6, 42), (5, 4, 20), (3, 2, 6), (1, 0, 0)])
def test_mul(calc, a, b, r):
    assert calc.mul(a, b) == r

@pytest.mark.parametrize("a, b, r", [(9, 3, 3), (8, 4, 2), (6, 2, 3), (4, 2, 2), (0, 1, 0)])
def test_div(calc, a, b, r):
    assert calc.div(a, b) == r

def test_div_error(calc):
    with pytest.raises(ZeroDivisionError):
        calc.div(1, 0)

テスト実行

py.testで実行可能
実行したディレクトリ配下を再帰的に探索し、
testで始まるpyファイルを実行してくれる。

テスト結果
成功例

============================= test session starts ==============================
platform darwin -- Python 3.5.1, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /Users/rotasuke/git/python_test/others, inifile: 
collected 21 items

test_calculator.py .....................

========================== 21 passed in 0.03 seconds ===========================

失敗例

============================= test session starts ==============================
platform darwin -- Python 3.5.1, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /Users/rotasuke/git/python_test/others, inifile: 
collected 21 items

test_calculator.py ...................F.

=================================== FAILURES ===================================
_______________________________ test_div[0-1-1] ________________________________

calc = <calculator.Calculator object at 0x10c9567f0>, a = 0, b = 1, r = 1

    @pytest.mark.parametrize("a, b, r", [(9, 3, 3), (8, 4, 2), (6, 2, 3), (4, 2, 2), (0, 1, 1)])
    def test_div(calc, a, b, r):
>       assert calc.div(a, b) == r
E       assert 0.0 == 1
E        +  where 0.0 = <bound method Calculator.div of <calculator.Calculator object at 0x10c9567f0>>(0, 1)
E        +    where <bound method Calculator.div of <calculator.Calculator object at 0x10c9567f0>> = <calculator.Calculator object at 0x10c9567f0>.div

test_calculator.py:21: AssertionError
===================== 1 failed, 20 passed in 0.04 seconds ======================

Jenkinsジョブ作成

Gitのチェックアウトなどの細かい設定は割愛する。

[ビルド]の[シェルの実行]に
py.test <実行するディレクトリ>
を指定する。

テストレポートの出力

先ほど入力した、実行するシェルスクリプトに
--junitxml=<出力先xmlファイル>
を指定することで、JUnit形式でテストレポートを出力することができる。

[ビルド後の処理]に、[JUnit テスト結果の集計]を追加し
先ほど出力したxmlファイルを指定する。

カバレッジの出力

pip install pytest-covでカバレッジ出力用のモジュールをインストール

先ほど入力した、実行するシェルスクリプトに
--cov-report=xml --cov
を指定することで、コマンド実行したディレクトリ配下にcoverage.xmlを出力することができる。

JenkinsのCobertura Pluginにcoverage.xmlを読ませることで可視化できる。

43
56
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
56