本記事の概要
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を読ませることで可視化できる。