2014-10-16 6 views
26

Utilizzo il selenio per test end-to-end e non riesco a ottenere l'utilizzo dei metodi setup_class e teardown_class.Come faccio ad impostare e rimuovere correttamente la mia classe pytest con i test?

Devo impostare il browser nel metodo setup_class, quindi eseguire una serie di test definiti come metodi di classe e, infine, chiudere il browser nel metodo teardown_clas s.

Ma logicamente sembra una soluzione sbagliata, perché in effetti i miei test non funzioneranno con la classe, ma con l'oggetto. Passo self param all'interno di ogni metodo di prova, in modo da poter accedere a Vars degli oggetti:

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 

E ancora sembra non essere corretto per creare l'istanza del browser per la classe .. E dovrebbe essere creato per ogni oggetto a parte, a destra ?

Quindi, devo utilizzare i metodi __init__ e __del__ anziché setup_class e teardown_class?

+0

+1 questo mi ha sempre infastidito. Perché non ci sono i metodi setup_instance (self) e teardown_instance (self)? (o forse setup/teardown_object?) Non sarebbe più corretto OO? – cbare

risposta

25

Quando si scrive "test definiti come metodi di classe", si fa davvero sul serio metodi della classe (metodi che ricevono la sua classe come primo parametro) o solo metodi regolari (metodi che ricevono un esempio come primo parametro)?

Dal momento che il tuo esempio utilizza self per i metodi di prova che sto assumendo quest'ultimo, in modo che solo bisogno di usare setup_method invece: metodo

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 

Il test istanza è passato a setup_method e teardown_method, ma può essere ignorato se il tuo codice di setup/teardown non ha bisogno di conoscere il contesto di test. Maggiori informazioni possono essere trovate here.

Mi raccomando anche di familiarizzare con py.test's fixtures, in quanto sono un concetto più potente.

+0

Perché hai scritto 'class Test' e non' class Test (object) '? –

+0

Mostro principalmente i miei esempi in Python 3, ecco perché non mi sono preoccupato. :) –

+0

Oh? Ho pensato che si dovrebbe scrivere 'class Test (object)', ma non sono troppo sicuro da dove l'ho preso. –

10

Come suggerito da @Bruno, l'uso di fixture pytest è un'altra soluzione accessibile sia per le classi di test sia per le semplici funzioni di test. 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..." 

Così, eseguendo test_1... produce:

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

noti che stuff_i_setup viene fatto riferimento nel dispositivo, permettendo che oggetto da setup e torn down per la prova è interagendo con. Si può immaginare che ciò potrebbe essere utile per un oggetto persistente, ad esempio un database ipotetico o una connessione, che deve essere cancellato prima dell'esecuzione di ogni test per tenerli isolati.

23

Secondo Fixture finalization/executing teardown code l'uso di addfinalizer è "storico".

Come nota storica, un altro modo per scrivere il codice di rimozione consiste nell'accettare un oggetto richiesta nella funzione fixture e può richiamare la sua richiesta.addfinalizer una o più volte:

La migliore prassi corrente per l'impostazione e teardown è quello di utilizzare yield

import pytest 

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

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

esecuzione si traduce in

$ 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 === 
+0

Quindi copi questo in ogni file di test di cui avrai bisogno la risorsa? –

+0

@AndyHayden A seconda di come si scrivono i dispositivi, è possibile inserirlo in ogni file di test in cui è necessario oppure inserirlo in un file conftest.py https://stackoverflow.com/questions/34466027/in-py- test-what-is-the-use-of-conftest-py-files –

+0

Questo tuttavia non è un setup di classe, giusto? Eseguirà prima di ogni metodo di test della classe. – malhar

1

Questo potrebbe aiutare http://docs.pytest.org/en/latest/xunit_setup.html

nella mia suite di test, ho gruppo miei casi di test in classi. Per il setup e il teardown di cui ho bisogno per tutti i test case in quella classe, utilizzo i metodi di classe setup_class(cls) e teardown_class(cls).

E per l'installazione e teardown ho bisogno per ciascuno dei test case, io uso il setup_method(method) e teardown_method(methods)

Esempio:

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 

Ora, quando eseguo il mio test, quando l'esecuzione TestClass è iniziando, registra i dettagli per quando inizia l'esecuzione, quando termina l'esecuzione e lo stesso per i metodi ..

È possibile aggiungere altri passaggi di impostazione e di smontaggio che si potrebbero avere nelle rispettive posizioni .

Spero che aiuti!