unittest-xml-reportingを用いてunittestの結果を表示する


今回のお題

今回のテーマはテスト結果の可視化です。

現在jenkinsという自動化ツールを用いてpythonのunittestの定期実行について学習しています。

そして、unittest-xml-reportionというライブラリを用いることでjenkinsに実行させたテストの結果をグラフ表示できるようになるとのことなので、今回はそれについて学んでいきたいと思います。

以下が表示されるグラフです。

なお、今回はjenkinsそのものの使い方については触れません。

必要であれば以下の記事をどうぞ。

目次

  • 今回実行するテスト
  • unittest-xml-reportingについて
  • ライブラリの導入
  • プラグインの導入
  • jenkinsプロジェクトの作成
  • 終わりに

今回実行するテスト

以下が今回実行するテストです。

別ファイルで定義した四則演算の関数をimportしてテストします。

calc.py
class Calculator(object):
  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)
testcase_4.py
import unittest
from calc import Calculator
from parameterized import parameterized

class MyTestCase(unittest.TestCase):

  @classmethod
  def setUpClass(cls) -> None:
    MyTestCase.calc = Calculator()
    print("create calculator")
    return super().setUpClass()

  @parameterized.expand([
    (10, 13, 23),
    (1, 3, 4),
    (3, 7, 10)
  ])
  def test_add(self, a, b, c):
    # calc = Calculator()
    self.assertEqual(MyTestCase.calc.add(a, b), c)

  def test_sub(self):
    # calc = Calculator()
    self.assertEqual(MyTestCase.calc.sub(15, 10), 5)

  def test_mul(self):
    # calc = Calculator()
    self.assertEqual(MyTestCase.calc.mul(5, 10), 50)

  def test_div(self):
    # calc = Calculator()
    # self.assertEqual(MyTestCase.calc.div(15, 5), 3)
    with self.assertRaises(ZeroDivisionError):
      # self.calc.div(5, 3)
      # return (5 / 0)
      return (5 / 3) # わざとエラーが発生するように設定

if __name__ == "__main__":
  unittest.main()

エラーが発生した場合にどのようにレポートされるのかが見たかったので、わざと一箇所失敗するようにしています。

では、ここにunittest-xml-reportingを導入してテスト結果が可視化されるようにしていきます。

unittest-xml-reportingとは

unittest-xml-reportingは本来はテスト実行結果をxmlファイルに出力するためのものです。

例えば上記のテストを実行すると、以下のようなファイルが作成されます。

<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="MyTestCase-20211108121938" tests="6" file=".py" time="0.003" timestamp="2021-11-08T12:19:38" failures="1" errors="0" skipped="0">
    <testcase classname="MyTestCase" name="test_add_0" time="0.002" timestamp="2021-11-08T12:19:38" file="testcase_4.py" line="531"/>
    <testcase classname="MyTestCase" name="test_add_1" time="0.000" timestamp="2021-11-08T12:19:38" file="testcase_4.py" line="531"/>
    <testcase classname="MyTestCase" name="test_add_2" time="0.000" timestamp="2021-11-08T12:19:38" file="testcase_4.py" line="531"/>
    <testcase classname="MyTestCase" name="test_mul" time="0.000" timestamp="2021-11-08T12:19:38" file="testcase_4.py" line="28"/>
    <testcase classname="MyTestCase" name="test_sub" time="0.000" timestamp="2021-11-08T12:19:38" file="testcase_4.py" line="24"/>
    <testcase classname="MyTestCase" name="test_div" time="0.000" timestamp="2021-11-08T12:19:38" file="testcase_4.py" line="32">
        <failure type="AssertionError" message="ZeroDivisionError not raised"><![CDATA[Traceback (most recent call last):
  File "testcase_4.py", line 38, in test_div
    return (5 / 3)
AssertionError: ZeroDivisionError not raised
]]></failure>
    </testcase>
</testsuite>

テストの実行ログやエラー内容が表示されていますね。

もちろんこれをそのまま利用しても良いのですが、テストの数が多くなると分かりにくくなりますよね。

なのでただunittest-xml-reportingを導入するだけでなくjenkins上でグラフ表示できるようにしてしまおうというのが今回の趣旨になります。

ライブラリの導入

まずはunittest-xml-reportingをテストに導入します。

% pip3 install unittest-xml-reporting

導入が完了したら、テストコードファイルを以下のように編集します。

# importの追加
import xmlrunner

# 最後の if __name__ == "__main__"の部分を変更
if __name__ == "__main__":
  unittest.main(
    testRunner=xmlrunner.XMLTestRunner(output="test_reports"),
    failfast=False,
    buffer=False,
    catchbreak=False
  )

outputで結果のxmlファイルの出力先を指定しています。

今回であればテストコードのファイルと同じディレクトリにtest_reportsというフォルダが作成され、その中にxmlファイルが追加されます。

また、testRunner以外のキーワード引数についてはドキュメントを見たところデフォルトでもfalseでした。

省略しても結果は変わらなかったのですが、参考にした書籍では明示されていたので念の為残しています。

これで結果をxml出力するところまでは設定できました。

次に、これをグラフ表示できるようにしていきます。

プラグインの導入

まずはjenkinsにプラグインを導入します。

jenkinsのトップページからJUnit Pluginを追加してください(推奨プラグインの中に含まれているので、追加済みの場合も多いかと思います)。

追加し終わったらプロジェクトの作成に移ります。

jenkinsプロジェクトの作成

基本的な方法は前回と同じで、そこに結果をグラフ表示する設定を追加します。

前回と異なるのは、

  • ビルド手順の中にライブラリのインストールを追加する
  • ビルド後の作業として、テスト結果の出力処理を追加する

の2点です。

一つ目についてですが、以下のようにライブラリのインストールをビルド手順に含めておかないとModuleNotFoundErrorが発生します。

二つ目についてですが、一番下のビルド後の処理の追加という項目からjunitテスト結果の集計を選択し、作成されるxmlファイルの相対パスを入力します。

今回はテストファイルと同じディレクトリにtest_reportsディレクトリが作成され、その中にxmlファイルが作られるのでtest_reports/*.xmlとワイルドカード指定をしておきます。

これで冒頭のようなテスト結果が表示されるようになります。

終わりに

以上でテスト結果の可視化ができるようになりました。

エラーの数などがすぐにわかるのが便利ですね。