web-dev-qa-db-ja.com

unittestのテスト間で変数の変更を保持しますか?

UnitttestでTestCaseを継承する同じオブジェクト内で行われた変更を保持するにはどうすればよいですか?

from unittest import TestCase, main as unittest_main


class TestSimpleFoo(TestCase):
    foo = 'bar'

    def setUp(self):
        pass

    def test_a(self):
        self.assertEqual(self.foo, 'bar')
        self.foo = 'can'

    def test_f(self):
        self.assertEqual(self.foo, 'can')


if __== '__main__':
    unittest_main()

I.e .:上記の2つのテストに合格する

39
A T

いくつかのコメントが反響したように、この方法でテストを構造化することはおそらくテスト自体の設計上の欠陥であり、再構築を検討する必要があります。ただし、これを実行し、使用しているテストランナーがアルファベット順に(一見)実行するという事実に依存する場合は、以下をお勧めします。

@Matthiasが言っていたことと似ていますが、後日クラスから継承することを決定する可能性がある場合には、1つのことを別の方法で行います。

from unittest import TestCase, main as unittest_main


class TestSimpleFoo(TestCase):
    foo = 'bar'

    def setUp(self):
        pass

    def test_a(self):
        self.assertEqual(self.__class__.foo, 'bar')
        self.__class__.foo = 'can'

    def test_f(self):
        self.assertEqual(self.__class__.foo, 'can')


if __== '__main__':
    unittest_main()

この回答と受け入れた@Matthiasの回答の違いは、クラスの明示的な宣言と、上記のクラス参照のルックアップです。

TestSimpleFoo vs self.__class__

後でテストを継承し、両方のテストクラスを連続して実行し、2つのクラスの間にクロスオーバーがないように、動的性を優先します。このクラスから継承することを選択した場合、クラス参照に明示的に名前を付けると、両方のテストクラスがそれぞれのクラスではなくその参照に対して実行されるためです。

48
rdp

私はそれの単純さのためにあなた自身の答えが好きですが、あなたが明確な単体テストを維持したい場合:

Unittestは、TestCaseの新しいインスタンスで個別のテストを実行しているようです。さて、永続化するオブジェクトを自分以外の何かにバインドするだけです。例えば:

from unittest import TestCase, main as unittest_main


class TestSimpleFoo(TestCase):

    def setUp(self):
        pass

    def test_a(self):
        TestSimpleFoo.foo = 'can'

    def test_f(self):
        self.assertEqual(TestSimpleFoo.foo, 'can')


if __== '__main__':
    unittest_main()

SetUpClassとtearDownClassにも興味があるかもしれません: https://docs.python.org/3/library/unittest.html#setupclass-and-teardownclass

ユニットテストの実行順序にも注意してください: https://docs.python.org/2/library/unittest.html#unittest.TestLoader.sortTestMethodsUsing

9
Matthias

理解できませんでした。そのため、複数のtest_接頭辞付き関数:

def test_password_credentials_grant(self):
    for user in self.user_mocks:
        self.register(user)
        self.login(user)
        self.access_token(user, self.assertEqual)  # Ensures access_token is generated+valid
        self.logout(user)
        self.access_token(user, self.assertNotEqual)  # Ensures access_token is now invalid
        self.unregister(user)
1
A T

他の人が言ったことに加えて、テストメソッド間のデータ共有をこの方法で実装すべきではありません。setup()を使用することをお勧めします。

テストメソッド自体は分離する必要があります。

0
Gearon