개발/Python

[Python] 테스트를 통해 pytest 클래스를 올바르게 설정하고 분해하려면 어떻게해야합니까?

MinorMan 2021. 4. 19. 04:55
반응형

<질문>

종단 간 테스트에 셀레늄을 사용하고 있는데 사용 방법을 알 수 없습니다.setup_classteardown_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?


<답변1>

에 따르면Fixture finalization / executing teardown code, 설정 및 해체에 대한 현재 모범 사례는yield대신에return:

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 object조명기 함수에 넣고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))

<답변2>

당신이 쓸 때"클래스 메소드로 정의 된 테스트", 정말 의미합니까수업 방법(수신하는 방법수업첫 번째 매개 변수로) 또는 일반 메소드 (첫 번째 매개 변수로)?

귀하의 예가 사용하기 때문에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_methodteardown_method하지만 설정 / 해체 코드가 테스트 컨텍스트를 알 필요가없는 경우 무시할 수 있습니다. 더 많은 정보를 찾을 수 있습니다here.

또한 py.test에 익숙해지는 것이 좋습니다.fixtures, 더 강력한 개념이기 때문입니다.


<답변3>

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

테스트 스위트에서 테스트 케이스를 클래스로 그룹화합니다. 해당 클래스의 모든 테스트 케이스에 필요한 설정 및 해체를 위해setup_class(cls)teardown_class(cls)classmethods.

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

예:

lh = 

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):
        
        assert 

    def test_tc2(self):
        
        assert

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

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

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


<답변4>

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

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상호 작용하는 테스트를 위해. 가상 데이터베이스 또는 일부 연결과 같은 영구 개체에 유용 할 수 있다고 상상할 수 있습니다. 이러한 개체는 격리 된 상태로 유지하기 위해 각 테스트를 실행하기 전에 지워야합니다.


<답변5>

코드를 추가하면 예상대로 작동합니다.@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/


<답변6>

import pytest
class Test:
    @pytest.fixture()
    def setUp(self):
        print("setup")
        yield "resource"
        print("teardown")

    def test_that_depends_on_resource(self, setUp):
        print("testing {}".format(setUp))

실행하려면 :

pytest nam_of_the_module.py -v 
반응형