मैं परीक्षण के साथ अपने सबसे प्यारे वर्ग के लिए सही ढंग से सेटअप और फाड़ कैसे करूं?


100

मैं अंत परीक्षण के लिए सेलेनियम का उपयोग कर रहा हूं और मुझे इसका उपयोग करने के तरीके setup_classऔर teardown_classतरीके नहीं मिल सकते हैं ।

मुझे setup_classविधि में ब्राउज़र सेट करने की आवश्यकता है , फिर कक्षा विधियों के रूप में परिभाषित परीक्षणों का एक गुच्छा निष्पादित करें और अंत में teardown_classविधि में ब्राउज़र छोड़ दें ।

लेकिन तार्किक रूप से यह एक बुरे समाधान की तरह लगता है, क्योंकि वास्तव में मेरे परीक्षण कक्षा के साथ नहीं, बल्कि ऑब्जेक्ट के साथ काम करेंगे। मैं selfहर परीक्षा पद्धति के अंदर परम उत्तीर्ण होता हूं , इसलिए मैं वस्तुओं के संस्करण तक पहुंच सकता हूं:

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_classऔर teardown_class?

जवाबों:


93

फिक्सेटर फाइनल / टैडडाउन कोड को निष्पादित करने के अनुसार , सेटअप और फाड़ के लिए वर्तमान सर्वोत्तम अभ्यास 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आंसू कोड लिखने का दूसरा तरीका यह है कि आप अपने फिक्सेटर फ़ंक्शन में एक- कॉन्टेक्स्ट ऑब्जेक्ट को स्वीकार करें और 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))

तो आप इसे हर उस परीक्षण फ़ाइल में कॉपी कर लेते हैं, जिसे आपको संसाधन की आवश्यकता है?
एंडी हेडन

कैसे आप अपने जुड़नार लिखने पर निर्भर करता है @AndyHayden, आप इसे हर परीक्षण फ़ाइल जहां आपको उसकी आवश्यकता में डाल सकता है या आप एक conftest.py फ़ाइल में डाल सकता है stackoverflow.com/questions/34466027/...
एवरेट Toews

2
यह एक वर्ग सेटअप नहीं है, है ना? यह कक्षा में प्रत्येक परीक्षण विधि से पहले निष्पादित होगा।
मल्हार

1
इस विशेष मामले में, इसे केवल तब निष्पादित किया जाता है जब परीक्षण पद्धति में इसे परम के रूप में उपयोग किया जाता है। resourceपरम में जैसेtest_that_depends_on_resource(self, resource)
एवरेट टॉस

64

जब आप "परीक्षण को क्लास के तरीकों के रूप में परिभाषित करते हैं" लिखते हैं , तो क्या आप वास्तव में क्लास के तरीकों ( पहले पैरामीटर के रूप में अपनी कक्षा प्राप्त करने वाले तरीकों ) या सिर्फ नियमित तरीकों ( पहले पैरामीटर के रूप में एक उदाहरण प्राप्त करने वाले तरीके) का मतलब है ?

चूँकि आपका उदाहरण 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 के जुड़नार के साथ परिचित करें , क्योंकि वे एक अधिक शक्तिशाली अवधारणा हैं।


1
फिक्स्चर वर्ग के तरीकों की तुलना में कमजोर हैं: वे उनके द्वारा बनाई गई वस्तुओं के विनाश की अनुमति नहीं देते हैं (जो कि वास्तव में आवश्यक है)। इसके अलावा, जानकारी के लिए धन्यवाद।
wvxvw

एक 3.0x के रिलीज से एक कोडबेस को अपग्रेड करते समय इसने मुझे हिट किया। 4.x वैरिएंट तक रिलीज किया। कुछ पुराने कोड का इस्तेमाल setup_classनकली तरीकों से किया गया और इस तरह जिन्हें आधुनिक बनाने की जरूरत थी। setup_class(self, foo, bar)->setup_method(self,function,foo,bar)
jxramos

28

यह 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

अब जब मैं अपने परीक्षण चलाता हूं, जब टेस्टक्लास निष्पादन शुरू हो रहा है, तो यह विवरणों को लॉग करता है कि यह निष्पादन कब शुरू कर रहा है, जब यह निष्पादन समाप्त कर रहा है और विधियों के लिए समान है।

आप अन्य सेटअप और फाड़ कदम जोड़ सकते हैं जो आपके पास संबंधित स्थानों में हो सकते हैं।

आशा करता हूँ की ये काम करेगा!


हाय @ कीरन, setup_classबनाम के बीच अंतर क्या है setup_method?
imsrgadich

1
@imsrgadich जब आप अपने परीक्षण मामलों को कक्षाओं में व्यवस्थित करते हैं, तो <setup / teardown> _class का उपयोग वर्ग के सेटअप और अशांति चरणों के लिए किया जाता है और <setup / teardown> _method प्रत्येक परीक्षण केस विधि के संबंधित चरण हैं।
किरण वेमुरी

1
धिक्कार है ... अब मैं समझ गया! कुछ घंटों के लिए उस पर अटक गया था। इसलिए, चीजों को परिप्रेक्ष्य में रखना। <setup/teardown>_classपूरी कक्षा के लिए। यहां, DB की लिंक सेट करने या डेटाफ़ाइल को लोड करने जैसी चीज़ें हो सकती हैं। और फिर, प्रत्येक परीक्षण मामले के रूप में अपना स्वयं का सेटअप हो सकता है <setup/teardown>_method। चीजें अब बहुत स्पष्ट हैं। आपका बहुत बहुत धन्यवाद!
imsrgadich

24

जैसा कि @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फिक्सेटर में संदर्भित है, उस ऑब्जेक्ट को अनुमति देता है setupऔर torn downउस परीक्षण के लिए जिसके साथ वह इंटरैक्ट कर रहा है। आप कल्पना कर सकते हैं कि यह किसी स्थायी ऑब्जेक्ट के लिए उपयोगी हो सकता है, जैसे कि एक काल्पनिक डेटाबेस या कुछ कनेक्शन, जो उन्हें अलग-थलग रखने के लिए प्रत्येक परीक्षण के चलने से पहले साफ़ किया जाना चाहिए।


13

यदि आप @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/ देखें


यह बहुत कुछ वही है जो प्रलेखन में दिखाई देता है। डॉक्टर के साथ मुझे जो परेशानी हुई वह यह थी कि मुझे संदर्भ को समझने में कठिनाई हुई: स्वयं को पारंपरिक रूप से स्वयं के रूप में संदर्भित किया जाता है, न कि क्लॉस के रूप में, इसलिए यह मुझे अजीब लगा, कक्षा के संदर्भ से बाहर। किरण (ऊपर) यह संदर्भ प्रदान करती है।
कोग्निटाइकलाइव्स

1
@Cognitiaclaeves "स्वयं को पारंपरिक रूप से स्वयं के रूप में संदर्भित किया जाता है, cls " हां, selfउदाहरण के तरीकों के लिए उपयोग किया जाता है, जहां पहला तर्क विशिष्ट ऑब्जेक्ट उदाहरण है जिस पर विधि ऑपरेशन हो रहा है, जबकि s के clsलिए उपयोग किया जाता है @classmethod, जो बाध्य है वर्ग और कक्षा का उदाहरण नहीं है (अर्थात एक वस्तु)।
code_dredd
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.