UnitTestフレームワーク-API

この章では、unittestモジュールで定義されているクラスとメソッドについて説明します。このモジュールには5つの主要なクラスがあります。

TestCaseクラス

このクラスのオブジェクトは、テスト可能な最小単位を表します。テストルーチンを保持し、各ルーチンを準備し、その後クリーンアップするためのフックを提供します。

以下のメソッドは、TestCaseクラスで定義されています-

シニア番号 方法と説明
1

setUp()

テストフィクスチャを準備するために呼び出されるメソッド。これは、テストメソッドを呼び出す直前に呼び出されます

2

tearDown()

テストメソッドが呼び出され、結果が記録された直後に呼び出されたメソッド。これは、テストメソッドで例外が発生した場合でも呼び出されます。

3

setUpClass()

個々のクラスの実行前に呼び出されるクラスメソッド。

4

tearDownClass()

個々のクラスのテストが実行された後に呼び出されるクラスメソッド。

5

run(result = None)

渡されたテスト結果オブジェクトに結果を収集し、テストを実行した結果

6

skipTest(reason)

テストメソッドまたはsetUp()中にこれを呼び出すと、現在のテストがスキップされます。

7

debug()

結果を収集せずにテストを実行します。

8

shortDescription()

テストの1行の説明を返します。

備品

TestCaseクラス内には多数のテストが記述されている可能性があります。これらのテスト方法では、データベース接続、一時ファイル、またはその他のリソースを初期化する必要がある場合があります。これらはフィクスチャと呼ばれます。TestCaseには、テストに必要なフィクスチャを構成およびクリーンアップするための特別なフックが含まれています。フィクスチャを設定するには、setUp()をオーバーライドします。クリーンアップするには、tearDown()をオーバーライドします。

次の例では、2つのテストがTestCaseクラス内に記述されています。2つの値の加算と減算の結果をテストします。setup()メソッドは、各テストのshortDescription()に基づいて引数を初期化します。teardown()メソッドは、各テストの最後に実行されます。

import unittest

class simpleTest2(unittest.TestCase):
   def setUp(self):
      self.a = 10
      self.b = 20
      name = self.shortDescription()
      if name == "Add":
         self.a = 10
         self.b = 20
         print name, self.a, self.b
      if name == "sub":
         self.a = 50
         self.b = 60
         print name, self.a, self.b
   def tearDown(self):
      print '\nend of test',self.shortDescription()

   def testadd(self):
      """Add"""
      result = self.a+self.b
      self.assertTrue(result == 100)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)
      
if __name__ == '__main__':
   unittest.main()

上記のコードをコマンドラインから実行します。次の出力が得られます-

C:\Python27>python test2.py
Add 10 20
F
end of test Add
sub 50 60
end of test sub
.
================================================================
FAIL: testadd (__main__.simpleTest2)
Add
----------------------------------------------------------------------
Traceback (most recent call last):
   File "test2.py", line 21, in testadd
      self.assertTrue(result == 100)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 2 tests in 0.015s

FAILED (failures = 1)

クラスフィクスチャ

TestCaseクラスにはsetUpClass()メソッドがあり、TestCaseクラス内の個々のテストを実行する前にオーバーライドして実行できます。同様に、tearDownClass()メソッドは、クラス内のすべてのテストの後に実行されます。どちらのメソッドもクラスメソッドです。したがって、@ classmethodディレクティブで装飾する必要があります。

次の例は、これらのクラスメソッドの使用法を示しています。

import unittest

class TestFixtures(unittest.TestCase):

   @classmethod
   def setUpClass(cls):
      print 'called once before any tests in class'

   @classmethod
   def tearDownClass(cls):
      print '\ncalled once after all tests in class'

   def setUp(self):
      self.a = 10
      self.b = 20
      name = self.shortDescription()
      print '\n',name
   def tearDown(self):
      print '\nend of test',self.shortDescription()

   def test1(self):
      """One"""
      result = self.a+self.b
      self.assertTrue(True)
   def test2(self):
      """Two"""
      result = self.a-self.b
      self.assertTrue(False)
      
if __name__ == '__main__':
unittest.main()

TestSuiteクラス

Pythonのテストフレームワークは、テストする機能に応じてテストケースインスタンスをグループ化できる便利なメカニズムを提供します。このメカニズムは、unittestモジュールのTestSuiteクラスによって利用可能になります。

次の手順は、テストスイートの作成と実行に関係しています。

Step 1 −TestSuiteクラスのインスタンスを作成します。

suite = unittest.TestSuite()

Step 2 −スイートのTestCaseクラス内にテストを追加します。

suite.addTest(testcase class)

Step 3 − makeSuite()メソッドを使用して、クラスからテストを追加することもできます

suite = unittest.makeSuite(test case class)

Step 4 −スイートに個別のテストを追加することもできます。

suite.addTest(testcaseclass(""testmethod")

Step 5 −TestTestRunnerクラスのオブジェクトを作成します。

runner = unittest.TextTestRunner()

Step 6 − run()メソッドを呼び出して、スイート内のすべてのテストを実行します

runner.run (suite)

TestSuiteクラスでは以下のメソッドが定義されています-

シニア番号 方法と説明
1

addTest()

テストスイートにテストメソッドを追加します。

2

addTests()

複数のTestCaseクラスからテストを追加します。

3

run()

このスイートに関連付けられたテストを実行し、結果をテスト結果オブジェクトに収集します

4

debug()

結果を収集せずに、このスイートに関連付けられたテストを実行します。

5

countTestCases()

このテストオブジェクトによって表されるテストの数を返します

次の例は、TestSuiteクラスの使用方法を示しています-

import unittest
class suiteTest(unittest.TestCase):
   def setUp(self):
      self.a = 10
      self.b = 20
      
   def testadd(self):
      """Add"""
      result = self.a+self.b
      self.assertTrue(result == 100)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)
      
def suite():
   suite = unittest.TestSuite()
##   suite.addTest (simpleTest3("testadd"))
##   suite.addTest (simpleTest3("testsub"))
   suite.addTest(unittest.makeSuite(simpleTest3))
   return suite
   
if __name__ == '__main__':
   runner = unittest.TextTestRunner()
   test_suite = suite()
   runner.run (test_suite)

makeSuite()メソッドを持つ行とコメントステートメントのコメントを解除することで、addTest()メソッドを試すことができます。

TestLoaderクラス

unittestパッケージには、クラスとモジュールからテストスイートを作成するために使用されるTestLoaderクラスがあります。デフォルトでは、unittest.main(0メソッドが呼び出されると、unittest.defaultTestLoaderインスタンスが自動的に作成されます。ただし、明示的なインスタンスを使用すると、特定のプロパティをカスタマイズできます。

次のコードでは、TestLoaderオブジェクトを使用して、2つのクラスのテストがリストに収集されます。

import unittest
testList = [Test1, Test2]
testLoad = unittest.TestLoader()

TestList = []
for testCase in testList:
   testSuite = testLoad.loadTestsFromTestCase(testCase)
   TestList.append(testSuite)
   
newSuite = unittest.TestSuite(TestList)
runner = unittest.TextTestRunner()
runner.run(newSuite)

次の表に、TestLoaderクラスのメソッドのリストを示します。

シニア番号 方法と説明
1

loadTestsFromTestCase()

TestCaseクラスに含まれるすべてのテストケースのスイートを返します

2

loadTestsFromModule()

指定されたモジュールに含まれるすべてのテストケースのスイートを返します。

3

loadTestsFromName()

文字列指定子を指定して、すべてのテストケースのスイートを返します。

4

discover()

指定された開始ディレクトリからサブディレクトリに再帰してすべてのテストモジュールを検索し、TestSuiteオブジェクトを返します

TestResultクラス

このクラスは、成功したテストと失敗したテストに関する情報をコンパイルするために使用されます。TestResultオブジェクトは、一連のテストの結果を格納します。TestResultインスタンスは、TestRunner.run()メソッドによって返されます。

TestResultインスタンスには次の属性があります-

シニア番号 属性と説明
1

Errors

2タプルのTestCaseインスタンスとフォーマットされたトレースバックを保持する文字列を含むリスト。各タプルは、予期しない例外を発生させたテストを表します。

2

Failures

2タプルのTestCaseインスタンスとフォーマットされたトレースバックを保持する文字列を含むリスト。各タプルは、TestCase.assert *()メソッドを使用して障害が明示的に通知されたテストを表します。

3

Skipped

TestCaseインスタンスの2タプルと、テストをスキップする理由を保持する文字列を含むリスト。

4

wasSuccessful()

これまでに実行されたすべてのテストに合格した場合はTrueを返し、それ以外の場合はFalseを返します。

5

stop()

このメソッドを呼び出して、実行中の一連のテストを中止する必要があることを通知できます。

6

startTestRun()

テストが実行される前に1回呼び出されます。

7

stopTestRun()

すべてのテストが実行された後に1回呼び出されます。

8

testsRun

これまでに実行されたテストの総数。

9

Buffer

trueに設定すると、 sys.stdout そして sys.stderrstartTest()とstopTest()が呼び出される間にバッファリングされます。

次のコードはテストスイートを実行します-

if __name__ == '__main__':
   runner = unittest.TextTestRunner()
   test_suite = suite()
   result = runner.run (test_suite)
   
   print "---- START OF TEST RESULTS"
   print result

   print "result::errors"
   print result.errors

   print "result::failures"
   print result.failures

   print "result::skipped"
   print result.skipped

   print "result::successful"
   print result.wasSuccessful()
   
   print "result::test-run"
   print result.testsRun
   print "---- END OF TEST RESULTS"

コードを実行すると、次の出力が表示されます-

---- START OF TEST RESULTS
<unittest.runner.TextTestResult run = 2 errors = 0 failures = 1>
result::errors
[]
result::failures
[(<__main__.suiteTest testMethod = testadd>, 'Traceback (most recent call last):\n
   File "test3.py", line 10, in testadd\n 
   self.assertTrue(result == 100)\nAssert
   ionError: False is not true\n')]
result::skipped
[]
result::successful
False
result::test-run
2
---- END OF TEST RESULTS