Python unittest を使ってみる

sugimoto です。

Pythonの単体テストのツール unittest を使ってみました。

1. まずはマニュアル通りに。。

Python – unittestのマニュアルから、TestSequenceFunctions を実行します。

# python testsequecefunctions.py
...
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK

普通に成功しましたね。

2. TestSuite を実行する

今度は複数のTestCaseからなる、TestSuiteを実行してみます。

TestCaseは同じものを使ったので、命名のセンスが悪くてすいません。。

2つのTestCaseをまとめて実行するTestSuite

[testsuite.py]

import unittest
import testsequecefunctions as TestSequenceFunctions
import testsequecefunctions2 as TestSequenceFunctions2

suite1 = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions.TestSequenceFunctions)
suite2 = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions2.TestSequenceFunctions2)
suite = unittest.TestSuite([suite1, suite2])
print suite.countTestCases()

runner = unittest.TextTestRunner()
runner.run(suite)

実行すると

# python testsuite.py
6
......
----------------------------------------------------------------------
Ran 6 tests in 0.002s

OK

6個のテストがすべてパスしました。

3. trac plugin をテストしてみる

trac のestimationtools pluginをテストしてみます。すでにテストコードも提供されているので、今回は実行するだけです。

# unzip estimationtoolsplugin-r6309.zip
# cd estimationtoolsplugin/trunk/estimationtools/tests
# ll
total 24
-rw-r--r-- 1 root root 9264 Jul 29 11:18 burndownchart.py
-rw-r--r-- 1 root root 2696 Jul 30 10:46 hoursremaining.py
-rw-r--r-- 1 root root 2283 Jan 26  2009 workloadchart.py

そのまま実行できるようにスクリプトの最後に以下のコードを追加しておきます。

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

そして実行

# python burndownchart.py
Traceback (most recent call last):
  File "burndownchart.py", line 3, in ?
    from estimationtools.burndownchart import BurndownChart
ImportError: No module named estimationtools.burndownchart

エラーになりました。。

estimationtools.burndownchart がないということですね。。

plugin 本体のディレクトリにパスを通しておきます。

# export PYTHONPATH=/root/plugins/estimationtoolsplugin/trunk/

再度実行します。

# python burndownchart.py
...FFF......
======================================================================
FAIL: test_calculate_timetable_with_closed_and_reopened_ticket (__main__.BurndownChartTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "burndownchart.py", line 140, in test_calculate_timetable_with_closed_and_reopened_ticket
    self.assertEqual(timetable, {day1: Decimal(10), day2: Decimal(0), day3: Decimal(0), day4: Decimal(5)})
AssertionError: {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("0"), datetime.date(2009, 8, 1): Decimal("0"), datetime.date(2009, 8, 2): Decimal("5")} != {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("10"), datetime.date(2009, 8, 1): Decimal("0"), datetime.date(2009, 8, 2): Decimal("5")}

======================================================================
FAIL: test_calculate_timetable_with_closed_ticket (__main__.BurndownChartTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "burndownchart.py", line 113, in test_calculate_timetable_with_closed_ticket
    self.assertEqual(timetable, {day1: Decimal(10), day2: Decimal(5), day3: Decimal(0)})
AssertionError: {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("0"), datetime.date(2009, 8, 1): Decimal("0")} != {datetime.date(2009, 7, 31): Decimal("5"), datetime.date(2009, 7, 30): Decimal("10"), datetime.date(2009, 8, 1): Decimal("0")}

======================================================================
FAIL: test_calculate_timetable_with_closed_ticket2 (__main__.BurndownChartTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "burndownchart.py", line 126, in test_calculate_timetable_with_closed_ticket2
    self.assertEqual(timetable, {day1: Decimal(10), day2: Decimal(0), day3: Decimal(0)})
AssertionError: {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("0"), datetime.date(2009, 8, 1): Decimal("0")} != {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("10"), datetime.date(2009, 8, 1): Decimal("0")}

----------------------------------------------------------------------
Ran 12 tests in 0.478s

FAILED (failures=3)
#

今度はうまくいった。。と思ったら、なぜかテストが失敗しましたね。。

4. estimationtools plugin のtest suite を実行する

estimationtools plugin には3つのテストがあるので、すべて実行するためのスクリプトを作ります。

[testsuite.py]

import unittest
import burndownchart as burndownchart
import hoursremaining as hoursremaining
import workloadchart as workloadchart

runner = unittest.TextTestRunner()
suite = unittest.TestLoader().loadTestsFromTestCase(burndownchart.BurndownChartTestCase)
runner.run(suite)

suite = unittest.TestLoader().loadTestsFromTestCase(hoursremaining.HoursRemainingTestCase)
runner.run(suite)

suite = unittest.TestLoader().loadTestsFromTestCase(workloadchart.WorkloadChartTestCase)
runner.run(suite)

3つのテストをロードして、実行するだけです。簡単です。

実行してみます。

# python testsuite.py
...FFF......
======================================================================
FAIL: test_calculate_timetable_with_closed_and_reopened_ticket (burndownchart.BurndownChartTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/root/plugins/estimationtoolsplugin/trunk/estimationtools/tests/burndownchart.py", line 140, in test_calculate_timetable_with_closed_and_reopened_ticket
    self.assertEqual(timetable, {day1: Decimal(10), day2: Decimal(0), day3: Decimal(0), day4: Decimal(5)})
AssertionError: {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("0"), datetime.date(2009, 8, 1): Decimal("0"), datetime.date(2009, 8, 2): Decimal("5")} != {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("10"), datetime.date(2009, 8, 1): Decimal("0"), datetime.date(2009, 8, 2): Decimal("5")}

======================================================================
FAIL: test_calculate_timetable_with_closed_ticket (burndownchart.BurndownChartTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/root/plugins/estimationtoolsplugin/trunk/estimationtools/tests/burndownchart.py", line 113, in test_calculate_timetable_with_closed_ticket
    self.assertEqual(timetable, {day1: Decimal(10), day2: Decimal(5), day3: Decimal(0)})
AssertionError: {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("0"), datetime.date(2009, 8, 1): Decimal("0")} != {datetime.date(2009, 7, 31): Decimal("5"), datetime.date(2009, 7, 30): Decimal("10"), datetime.date(2009, 8, 1): Decimal("0")}

======================================================================
FAIL: test_calculate_timetable_with_closed_ticket2 (burndownchart.BurndownChartTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/root/plugins/estimationtoolsplugin/trunk/estimationtools/tests/burndownchart.py", line 126, in test_calculate_timetable_with_closed_ticket2
    self.assertEqual(timetable, {day1: Decimal(10), day2: Decimal(0), day3: Decimal(0)})
AssertionError: {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("0"), datetime.date(2009, 8, 1): Decimal("0")} != {datetime.date(2009, 7, 31): Decimal("0"), datetime.date(2009, 7, 30): Decimal("10"), datetime.date(2009, 8, 1): Decimal("0")}

----------------------------------------------------------------------
Ran 12 tests in 0.619s

FAILED (failures=3)
.....
----------------------------------------------------------------------
Ran 5 tests in 0.692s

OK
..
----------------------------------------------------------------------
Ran 2 tests in 0.126s

OK

1つめのテストケースはやっぱり失敗しますが、残りのテストケースはすべて成功しました。

今回は既存のplugin に添付されているテストケースを使いましたが、自分がpluginを作ったときもテストケースを書きたいと思います。

参考

コメントを残す

メールアドレスが公開されることはありません。