2017-10-16 1 views
1

내 자동화 프레임 워크는 픽스처 대신 pytest setup/teardown 유형의 테스트를 사용합니다. 또한 여러 클래스의 레벨이 있습니다pytest : 설정/티어 다운 방법 중 매개 변수 값 가져 오기

BaseClass을 - 높은, 모든 테스트가 inhriet에서 그것을

FeatureClass - 그것은

TestClass에서 매체, 프로그램과 관련된 모든 테스트는 상속 기능 - 실제 시험을 개최

편집, 예제를 위해서, 나는

I가 원하는 DB는 간단한 인쇄 호출 변경 모든 setup/teardowns에 DB 보고서를 추가하십시오. 즉, 일반 BaseClasssetup_method이 테스트 용 DB 항목을 만들고 teardown_method이 항목을 결과로 변경하려고합니다. 나는 시도했지만 런타임 중에 실행중인 테스트의 값을 메소드에서 가져올 수 없다. 심지어 가능할까요? 그렇지 않다면 어떻게해야합니까?

샘플 : (base.py)에 너무

class TestClass(my_feature.MyFeature): 

    @pytest.mark.parametrize("fragment_length", [1,5,10])  
    def test_my_first_test(self): 
     # do stuff that is changed based on fragment_length 
     assert verify_stuff(fragment_length) 

(test_my_feature.py)에

class MyFeature(base.Base): 

    def setup_method(self, method): 
     # enable this feature in program 
     return True 

어떻게 수 (my_feature.py)에

class Base(object): 

    test_number = 0 
    def setup_method(self, method): 
     Base.test_number += 1 
     self.logger.info(color.Blue("STARTING TEST")) 
     self.logger.info(color.Blue("Current Test: {}".format(method.__name__))) 
     self.logger.info(color.Blue("Test Number: {}".format(self.test_number))) 
     # --->here i'd like to do something with the actual test parameters<--- 
     self.logger.info("print parameters here") 

    def teardown_method(self, method): 
     self.logger.info(color.Blue("Current Test: {}".format(method.__name__))) 
     self.logger.info(color.Blue("Test Number: {}".format(self.test_number))) 
     self.logger.info(color.Blue("END OF TEST")) 

테스트 프레임 워크의 기본 상위 클래스 인 setup_method에서 매개 변수를 가져 오겠습니까?

+0

당신이'unittest.TestCase'를 사용하고 있습니까 : 여기

는 실행입니까? 그런 다음'setup '의 값을'self'로 설정하고 테스트에서 가져올 수 있습니다. 이 질문에 대답하기 위해 샘플 코드와 같은 세부 정보가 필요합니다. – Arunmozhi

+0

@Arunmozhi 몇 가지 기본 코드를 추가했습니다. 내가하려고하는 것을 분명히 할 수 있기를 바랍니다. –

답변

2

간략한 답변 : 아니오, 당신은 이것을 할 수 없습니다. 그리고 네, 그 문제를 해결할 수 있습니다.


이상 비트 : & 분해 분석 만 유닛 테스트에 스타일 검사와의 호환성을 위해 수행됩니다 이러한 유닛 테스트 스타일의 설정. 그들은 pytest를 좋게 만드는 pytest의 fixture를 지원하지 않습니다.

이 때문에 pytest 또는 pytest의 unittest 플러그인은 이러한 설정/해제 방법에 대한 컨텍스트를 제공하지 않습니다. request, function 또는 기타 컨텍스트 객체가있는 경우 request.getfuncargvalue('my_fixture_name')을 통해 조명기 값을 동적으로 가져올 수 있습니다.

그러나 테스트 방법 개체 자체 (즉, 테스트 테스트 노드가 아님)는 모두 self/clsmethod입니다. ,

class TestCaseFunction(Function): 
    _excinfo = None 

    def setup(self): 
     self._testcase = self.parent.obj(self.name) 
     self._fix_unittest_skip_decorator() 
     self._obj = getattr(self._testcase, self.name) 
     if hasattr(self._testcase, 'setup_method'): 
      self._testcase.setup_method(self._obj) 
     if hasattr(self, "_request"): 
      self._request._fillfixtures() 

먼저 setup_method() 완전히 pytest의 객체 (테스트 노드로, 예를 들어 self)에서 분리라는 것을 참고 : _pytest/unittest.py 플러그인의 내부를 보면

, 당신은이 코드를 찾을 수 있습니다.

둘째, 조명기는 setup_method()이 호출 된 후에 준비됩니다. 따라서 사용자가 액세스 할 수있는 경우에도 준비가되지 않습니다.

일반적으로 일부 속임수 없이는이 작업을 수행 할 수 없습니다.책략을 위해


, 당신은 실행중인 한 번 pytest 후크/hookwrapper을 정의하고 pytest 노드를 기억해야한다 :

conftest.py 또는 기타 플러그인 :

import pytest 

@pytest.hookimpl(hookwrapper=True) 
def pytest_runtest_protocol(item, nextitem): 
    item.cls._item = item 
    yield 

test_me.py :

import pytest 


class Base(object): 
    def setup_method(self, method): 
     length = self._item.callspec.getparam('fragment_length') 
     print(length) 


class MyFeature(Base): 
    def setup_method(self, method): 
     super().setup_method(method) 


class TestClass(MyFeature): 
    @pytest.mark.parametrize("fragment_length", [1,5,10])  
    def test_my_first_test(self, fragment_length): 
     # do stuff that is changed based on fragment_length 
     assert True # verify_stuff(fragment_length) 

또한 MyFeature.setup_method() 뮤 st는 부모의 super(...).setup_method()를 명백한 이유로 부릅니다.

cls._item은 각 callspec (각 매개 변수가있는 각 함수 호출)에 설정됩니다. 원하는 경우 항목이나 특정 매개 변수를 다른 전역 상태로 설정할 수도 있습니다.

필드를 item.instance에 저장하지 않도록주의하십시오. 나중에 클래스 인스턴스가 만들어 지므로 setup_instance/teardown_instance 메서드를 사용해야합니다. 그렇지 않으면 저장된 인스턴스의 필드가 보존되지 않고 self._itemsetup_method()으로 사용할 수 없습니다.

============ test session starts ============ 
...... 
collected 3 items                                         

test_me.py::TestClass::test_my_first_test[1] 1 
PASSED 
test_me.py::TestClass::test_my_first_test[5] 5 
PASSED 
test_me.py::TestClass::test_my_first_test[10] 10 
PASSED 

============ 3 passed in 0.04 seconds ============ 
+0

자세한 답장을 보내 주셔서 감사합니다. pytest를 더 잘 이해할 수있었습니다. 나는 이것을 시도하고 구현할 것입니다. 나는 당신이 명시 적으로 'fragment_length'를 사용하여 값을 얻는 것을 보았습니다. 그래서 모든 매개 변수를 얻고 싶다면 self._item.callspec.params를 얻고 그 값을 반복 할 필요가 있습니까? –

+1

@AvishayCohen 나는 확실히 말할 수는 없지만, 아마도 그렇습니다. 여기에있는 모든 필드와 메소드는 pytest의 고급 API의 일부입니다. 유일한 문제는 item/node/callspec이 unittest의 클래스/메소드에 노출되지 않는다는 것입니다. 내 생각에, 그것은 unittest와의 하위 호환성을 위해 고안된 것이며 일반적인 pytest 사용법으로는 생각지 않습니다. –

+0

예. 그것은 위대한 작품! –

관련 문제