Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

本記事の概要

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を読ませることで可視化できる。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away