[python] 테스트를 통해 pytest 클래스를 올바르게 설정하고 분해하는 방법은 무엇입니까?

엔드 투 엔드 테스트를 위해 셀레늄을 사용 setup_class하고 있으며 사용 teardown_class방법 과 방법 을 얻을 수 없습니다 .

setup_class메서드에서 브라우저를 설정 한 다음 클래스 메서드로 정의 된 여러 테스트를 수행하고 마지막으로 teardown_class메서드 에서 브라우저를 종료해야합니다 .

그러나 논리적으로 그것은 나쁜 해결책처럼 보입니다. 사실 내 테스트는 클래스가 아니라 객체로 작동하기 때문입니다. self모든 테스트 메서드 내에서 매개 변수를 전달 하므로 개체의 var에 액세스 할 수 있습니다.

class TestClass:

    def setup_class(cls):
        pass

    def test_buttons(self, data):
        # self.$attribute can be used, but not cls.$attribute?  
        pass

    def test_buttons2(self, data):
        # self.$attribute can be used, but not cls.$attribute?
        pass

    def teardown_class(cls):
        pass
    

그리고 클래스에 대한 브라우저 인스턴스를 생성하는 것도 옳지 않은 것 같습니다. 모든 객체에 대해 개별적으로 생성해야합니다.

그래서, 사용할 필요가 __init____del__대신의 방법 setup_classteardown_class?



답변

Fixture 마무리 / 해체 코드 실행 에 따르면 설정 및 해체에 대한 현재 모범 사례 yieldreturn다음 대신 사용하는 것입니다 .

import pytest

@pytest.fixture()
def resource():
    print("setup")
    yield "resource"
    print("teardown")

class TestResource:
    def test_that_depends_on_resource(self, resource):
        print("testing {}".format(resource))

그것을 실행하면

$ py.test --capture=no pytest_yield.py
=== test session starts ===
platform darwin -- Python 2.7.10, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
collected 1 items

pytest_yield.py setup
testing resource
.teardown


=== 1 passed in 0.01 seconds ===

분해 코드를 작성하는 또 다른 방법은 request-context 객체 를 조명기 함수 에 받아들이고 request.addfinalizer분해를 한 번 또는 여러 번 수행하는 함수로 메서드를 호출하는 것입니다.

import pytest

@pytest.fixture()
def resource(request):
    print("setup")

    def teardown():
        print("teardown")
    request.addfinalizer(teardown)

    return "resource"

class TestResource:
    def test_that_depends_on_resource(self, resource):
        print("testing {}".format(resource))


답변

“클래스 메서드로 정의 된 테스트” 를 작성할 때 실제로 클래스 메서드 ( 클래스 를 첫 번째 매개 변수로 받는 메서드 ) 또는 일반 메서드 ( 인스턴스 를 첫 번째 매개 변수로 받는 메서드 )를 의미합니까?

귀하의 예제는 self테스트 방법을 사용 하기 때문에 후자를 가정하고 있으므로 setup_method대신 사용해야 합니다.

class Test:

    def setup_method(self, test_method):
        # configure self.attribute

    def teardown_method(self, test_method):
        # tear down self.attribute

    def test_buttons(self):
        # use self.attribute for test

테스트 메서드 인스턴스는 setup_method및에 전달 teardown_method되지만 설정 / 해체 코드가 테스트 컨텍스트를 알 필요가없는 경우 무시할 수 있습니다. 자세한 정보는 여기 에서 찾을 수 있습니다 . .

또한 py.test의 fixtures 는 더 강력한 개념이므로 익숙해지는 것이 좋습니다 .


답변

http://docs.pytest.org/en/latest/xunit_setup.html에 도움이 될 수 있습니다.

테스트 스위트에서 테스트 케이스를 클래스로 그룹화합니다. 내가 그 클래스의 모든 테스트 케이스에 필요한 설치 및 해체를 들어, 내가 사용 setup_class(cls)하고 teardown_class(cls)classmethods을.

그리고 각 테스트 케이스에 필요한 설정 및 해체를 위해 setup_method(method)teardown_method(methods)

예:

lh = <got log handler from logger module>

class TestClass:
    @classmethod
    def setup_class(cls):
        lh.info("starting class: {} execution".format(cls.__name__))

    @classmethod
    def teardown_class(cls):
        lh.info("starting class: {} execution".format(cls.__name__))

    def setup_method(self, method):
        lh.info("starting execution of tc: {}".format(method.__name__))

    def teardown_method(self, method):
        lh.info("starting execution of tc: {}".format(method.__name__))

    def test_tc1(self):
        <tc_content>
        assert

    def test_tc2(self):
        <tc_content>
        assert

이제 테스트를 실행할 때 TestClass 실행이 시작될 때 실행 시작시기, 실행 종료시기 및 메서드에 대한 세부 정보를 기록합니다.

각 위치에있을 수있는 다른 설정 및 해체 단계를 추가 할 수 있습니다.

도움이 되었기를 바랍니다.


답변

@Bruno가 제안했듯이 pytest 픽스처를 사용하는 것은 두 테스트 클래스 또는 단순한 테스트 기능에 대해 액세스 할 수있는 또 다른 솔루션입니다. 다음은 python2.7 함수를 테스트하는 예입니다 .

import pytest

@pytest.fixture(scope='function')
def some_resource(request):
    stuff_i_setup = ["I setup"]

    def some_teardown():
        stuff_i_setup[0] += " ... but now I'm torn down..."
        print stuff_i_setup[0]
    request.addfinalizer(some_teardown)

    return stuff_i_setup[0]

def test_1_that_needs_resource(some_resource):
    print some_resource + "... and now I'm testing things..."

따라서 실행 test_1...하면 다음이 생성됩니다.

I setup... and now I'm testing things...
I setup ... but now I'm torn down...

공지 사항 stuff_i_setup그 객체가 될 수 있도록 고정 장치에서 참조 setuptorn down테스트 것이 상호 작용입니다. 가상 데이터베이스 또는 일부 연결과 같은 영구 개체에 유용 할 수 있다고 상상할 수 있습니다. 이러한 개체는 격리 상태를 유지하기 위해 각 테스트를 실행하기 전에 지워야합니다.


답변

@classmethod데코레이터 를 추가하면 코드가 예상대로 작동 합니다.

@classmethod
def setup_class(cls):
    "Runs once per class"

@classmethod
def teardown_class(cls):
    "Runs at end of class"

http://pythontesting.net/framework/pytest/pytest-xunit-style-fixtures/ 참조


답변