일련의 자동화 된 테스트에 대해 setUp을 한 번만 실행


81

내 Python 버전은 2.6입니다.

모든 테스트에 필요한 작업을 수행하기 때문에 테스트 setUp 메서드를 한 번만 실행하고 싶습니다.

내 생각은 첫 번째 실행 후 'true'로 설정되는 부울 변수를 만든 다음 설정 메서드에 대한 둘 이상의 호출을 비활성화하는 것입니다.

class mySelTest(unittest.TestCase):
    setup_done = False

    def setUp(self):
        print str(self.setup_done)
            
        if self.setup_done:
            return
        self.setup_done = True
        print str(self.setup_done)

출력 :

False

True

--- Test 1 ---

False

True

--- Test 2 ---

왜 이것이 작동하지 않습니까? 내가 놓친 것이 있습니까?


6
Unittest는 각 테스트에 대해 별도의 인스턴스를 생성합니다
David Robinson

2
이러지마 다른 메커니즘을 구현하십시오. 그러나의 의미를 바꾸려고하지 마십시오 setUp.
David Heffernan

답변:


114

setUpClass테스트 스위트 당 한 번만 실행되는 메소드를 정의 하는 데 사용할 수 있습니다 .


답장을 보내 주셔서 감사합니다. Python 2.6.6을 사용하고 있으므로 setUpClass를 사용할 수 없습니다.
Kesandal

2
@JohnM .: unittest2 백 포트 패키지를 다운로드하고 이전 python-dist에서 모든 새로운 내용을 얻을 수 있습니다.
Macke 2013-01-14

이 질문은 Python 2를 다루지 만 대답은 Python 3에서도 유효하므로 Python 2가 더 이상 사용되지 않기 때문에 URL을 변경했습니다.
CharlesB

66

다니엘의 대답은 정확하지만 여기에 같은 호출하지 내가 찾은 몇 가지 일반적인 실수 피하기 위해 예이다 super()setUpClass()경우 TestCase의 서브 클래스 unittest.TestCase(처럼 django.testfalcon.testing)를.

에 대한 설명서 에는 이러한 경우 setUpClass()전화해야한다고 언급 되어 있지 않습니다 super(). 이 관련 질문 에서 볼 수 있듯이 그렇지 않으면 오류가 발생합니다 .

class SomeTest(TestCase):
    def setUp(self):
        self.user1 = UserProfile.objects.create_user(resource=SomeTest.the_resource)

    @classmethod
    def setUpClass(cls):
        """ get_some_resource() is slow, to avoid calling it for each test use setUpClass()
            and store the result as class variable
        """
        super(SomeTest, cls).setUpClass()
        cls.the_resource = get_some_resource()

1
TestCase하위 클래스 인 경우에만 관련됩니다 unittest.TestCase.
EliadL

3

당신 때문에 당신이 이동하시기 바랍니다 1.9+ 장고를 사용하는 것에까지 ... 테스트를 위해 일부 데이터를로드 할 필요성 여기 끝난 경우 setUpTestData :

class MyTests(TestCase):

    @classmethod
    def setUpTestData(cls):
        # Set up data for the whole TestCase
        cls.foo = Foo.objects.create(bar="Test")

    def test1(self):
        self.assertEqual(self.foo.bar, 'Test') 

2

setUp 호출을 중복 제거하지 말고 한 번만 호출하십시오.

예를 들면 :

class MyClass(object):
    ...

def _set_up():
    code to do one-time setup

_set_up()

모듈이 처음로드 될 때 _set_up ()을 호출합니다. 모듈 수준 함수로 정의했지만 MyClass의 클래스 메서드로 만들 수도 있습니다.


2

설정하려는 모든 코드를 mySelTest 외부에 한 번 배치합니다.

setup_done = False

class mySelTest(unittest.TestCase):

    def setUp(self):
        print str(setup_done)

        if setup_done:
            return

        setup_done = True
        print str(setup_done)

또 다른 가능성은에서 인스턴스화하는 Singleton 클래스를 갖는 것입니다.이 클래스 setUp()__new__코드를 한 번만 실행 하고 나머지 호출에 대해 개체 인스턴스를 반환합니다. 참조 : 싱글 톤을 정의하는 간단하고 우아한 방법이 있습니까?

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(
                            cls, *args, **kwargs)
            # PUT YOUR SETUP ONCE CODE HERE!
            cls.setUpBool = True

        return cls._instance

class mySelTest(unittest.TestCase):

    def setUp(self):
        # The first call initializes singleton, ever additional call returns the instantiated reference.
        print(Singleton().setUpBool)

당신의 방식도 작동합니다.


2

setup_done은 인스턴스 변수가 아니라 클래스 변수입니다.

인스턴스 변수로 참조하고 있습니다.

self.setup_done

하지만 클래스 변수로 참조해야합니다.

mySelTest.setup_done

수정 된 코드는 다음과 같습니다.

class mySelTest(unittest.TestCase):
    setup_done = False

    def setUp(self):
        print str(mySelTest.setup_done)

        if mySelTest.setup_done:
            return
        mySelTest.setup_done = True
        print str(mySelTest.setup_done)

2

저는 Python 3 cls을 사용하고 있으며 setup메서드 에서도 참조를 사용할 수 있으므로 다음과 같이 작동합니다.

class TestThing(unittest.TestCase):

  @classmethod
  def setUpClass(cls):
    cls.thing = Thing() # the `thing` is only instantiated once

  def setup(self):
    self.thing = cls.thing # ...but set on each test case instance

  def test_the_thing(self):
    self.assertTrue(self.thing is not None)

1
인스턴스 메서드 인 setUp 내에서 cls에 액세스 할 수 없습니다 (단위 테스트 setUp 메서드도 아니고 'test'로 시작하는 메서드도 아니기 때문에 소문자 setup ()가 호출되지 않습니다. 당신이 setUpClass의 클래스 변수를 정의하면 오류가) 그러나, 당신은 단순히 모든 인스턴스 메서드에 self.thing를 호출 할 수 있습니다
khuang834

감사합니다, @ khuang834. 네가 옳아. 이것은 나의 감독이었습니다.
Greg Ross

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.