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

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

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

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

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

[![Image from Gyazo](https://i.gyazo.com/ef5cc20645c2f11386066c544b77a65e.png)](https://gyazo.com/ef5cc20645c2f11386066c544b77a65e)

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

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

https://qiita.com/keishi04hrikzira/items/180611da1858a83aff4f

https://qiita.com/keishi04hrikzira/items/b5a3d2c9401dab39970a

目次
-

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

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

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

```python: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)
```
```python: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
<?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をテストに導入します。

```shell
% pip3 install unittest-xml-reporting
```

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

```python
# 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プロジェクトの作成
-
基本的な方法は前回と同じで、そこに結果をグラフ表示する設定を追加します。

https://qiita.com/keishi04hrikzira/items/b5a3d2c9401dab39970a

前回と異なるのは、

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

の2点です。

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

[![Image from Gyazo](https://i.gyazo.com/f339f61007d9b50b605df5e6f8b0292f.png)](https://gyazo.com/f339f61007d9b50b605df5e6f8b0292f)

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

[![Image from Gyazo](https://i.gyazo.com/937145352e67f64f841c472a15e0fca1.png)](https://gyazo.com/937145352e67f64f841c472a15e0fca1)

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

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

終わりに
-

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

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