web-dev-qa-db-ja.com

Python unittestのsetUp()とsetUpClass()の違いは何ですか?

Python unittestフレームワークのsetUp()setUpClass()の違いは何ですか?セットアップが1つのメソッドで処理されるのはなぜですか?その他?

setUp()およびsetUpClass()関数と同様に、tearDown()およびtearDownClass()関数でセットアップのどの部分が行われるかを理解したいと思います。

73
etja

クラスに複数のテストメソッドがある場合、違いが現れます。 setUpClassおよびtearDownClassは、クラス全体に対して1回実行されます。 setUptearDownは、各テストメソッドの前後に実行されます。

例えば:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    def setUp(self):
        print("setUp")

    def test1(self):
        print("test1")

    def test2(self):
        print("test2")

    def tearDown(self):
        print("tearDown")

    @classmethod
    def tearDownClass(cls):
        print("tearDownClass")

このテストを実行すると、次の情報が出力されます。

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(ドット(.)は、テストに合格したときのunittestのデフォルト出力です。)test1の前後にsetUptearDownが現れることに注意してください- andtest2。一方、setUpClasstearDownClassは、テストケース全体の最初と最後に1回だけ表示されます。

117

Python unittestフレームワークのsetUp()setUpClass()の違いは何ですか?

主な違い(Benjamin Hodgsonの回答に記載されているように)は、setUpClassが1回だけ呼び出され、すべてのテストの前に呼び出されるのに対して、setUpは各テストの直前に呼び出されます。 (注:Pythonのunittestだけでなく、他のxUnitテストフレームワークの同等のメソッドにも同じことが当てはまります。)

unittestから ドキュメント

setUpClass()

個々のクラスのテストが実行される前に呼び出されるクラスメソッド。 setUpClassは、クラスを唯一の引数として呼び出され、classmethod()として修飾する必要があります。

_@classmethod
def setUpClass(cls):
    ...
_

そして:

setUp()

テストフィクスチャを準備するために呼び出されるメソッド。これは、テストメソッドを呼び出す直前に呼び出されます。 AssertionErrorまたはSkipTestを除き、このメソッドによって発生した例外は、テストの失敗ではなくエラーと見なされます。デフォルトの実装は何もしません。

ある方法でセットアップが他の方法で処理されるのはなぜですか?

質問のこの部分はまだ回答されていません。 Gearonの回答に対する私のコメントによると、setUpメソッドは、すべてのテストに共通するフィクスチャの要素を対象としています(各テストでそのコードの重複を避けるため)。重複を削除すると(通常)可読性が向上し、メンテナンスの負担が軽減されるため、これは多くの場合便利です。

setUpClassメソッドは、データベース接続を開く、ファイルシステム上の一時ファイルを開く、テスト用の共有ライブラリをロードするなど、一度だけ実行する必要がある高価な要素に使用します。各テストはテストスイートの速度を大幅に低下させるため、すべてのテストの前に一度だけ実行します。これは、テストの独立性のわずかな低下ですが、状況によっては必要な最適化です。おそらく、データベース/ファイルシステム/ライブラリ/何でも本物を使わずにモックすることができるので、ユニットテストでそのようなことをするべきではありません。そのため、setUpClassはほとんど必要ありません。ただし、上記の例(または同様の)のテストが必要になったときに役立ちます。

2
Biggsy

質問と受け入れられた答えの両方を読んだ後、私はいくつかの補足ができると思います。

Q:セットアップが他のメソッドよりも1つのメソッドで処理されるのはなぜですか?
A:テスト方法には予備が必要な場合があり、予備はテスト方法によって異なるためです。

たとえば、サンプルとして https://www.tutorialspoint.com/unittest_framework/unittest_framework_api.htm のコードを以下に示します。

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 == 30)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)

if __== '__main__':
   unittest.main()

メソッドtestaddtestsubは異なる入力を必要とし、setUpメソッドでそれぞれ入力の値を設定できます。

0
Gearon