2012-12-09 7 views
6

Sto scrivendo una suite di test per un'applicazione Web utilizzando TestNG e Selenium WebDriver.TestNG Eseguire tutti i metodi di classe più volte facendo preliminarmente @BeforeClass con i dati forniti

Ciò di cui ho bisogno è eseguire tutti i metodi della classe di test più volte per diversi utenti autenticati (i dati vengono estratti in fase di esecuzione: da un DB). Quindi ho bisogno di passare un dato alla classe con il fornitore di dati, che fornisce le credenziali di tutti gli utenti, quindi per ogni utente ho bisogno di creare un driver web (per la purezza dell'esperimento) e autenticare con le credenziali fornite nel metodo @BeforeClass, eseguire tutti i metodi @Test della classe e creare un driver Web di chiusura a strappo @AfterClass.

Come posso farlo?

I miei tentativi di fare questo sono qui: https://gist.github.com/4246674

Attempt1 è stato quello di mettere un @Test(dataProvider="getUsersIdAndName") su di classe. Non funziona perché come risultava @Test(dataProvider=) sulla classe non significa che tutti i metodi della classe dovrebbero essere richiamati con i dati forniti. Il risultato è stato che il metodo non è stato invocato affatto perché non ci sono dati da passare ad esso argomenti. E ottengo strano rapporto di prova in cui questo metodo è contrassegnato come passato con un tempo di esecuzione di 0 sec. (È un progetto Maven aperto in NetBeans, se questo ha senso.)

Il @Test(dataProvider=) sulla classe significa qualcosa?

Tentativo2 era di aggiungere dataProvider sull'annotazione @Test del metodo. Non funziona perché ciò significa che il metodo di prova viene invocato due volte durante l'esecuzione della singola classe. Il risultato è stato che al secondo tentativo fallisce perché tenta di ripetere il test mentre il web driver non è stato reinizializzato: il browser esegue già il rendering di un'altra pagina.

Inoltre ci sono degli svantaggi del primo e del secondo tentativo che il log in se stesso viene eseguito nel metodo di prova piuttosto che nel metodo @BeforeClass perché non conosco alcun modo per fornirli con i dati dal fornitore di dati.

Tentativo3 era un tentativo disperato di combinare @BeforeClass e @Test sul singolo metodo. Non funziona perché @BeforeClass richiede anche @Parameters se un metodo annotato ha un elenco di parametri. Il risultato è che questo metodo viene invocato tre volte: la prima volta come un'installazione di classe quando fallisce a causa del motivo sopra e due volte a causa del provider di dati quando riesce.

Poi ho scoperto che TestNG non fornisce un modo per richiamare tutti i metodi della classe più volte con dati diversi: http://comments.gmane.org/gmane.comp.java.testng.user/864

Ho altre due idee di come posso archiviare lo stesso effetto.

Idea4 deve posizionare un @Test(dataProvider=) su ciascun metodo di prova, ciascun metodo eseguirà un'autenticazione e il test isAuthenticated() da solo e quindi eseguirà il proprio test. Inefficace e brutto.

Idea5 che si presenta come il migliore a prezzi accessibili è quello di contrassegnare con un solo metodo @Test che aggregare tutti gli altri metodi di prova: riceve dati dal provider di dati, esegue l'autenticazione da parte determinato utente, poi corre prova isAuthenticated e tutti gli altri necessari test.In questo caso, @BeforeClass e @AfterClass stanno solo configurando e distruggendo il driver web. Questo approccio ha lo svantaggio che sto perdendo la capacità di utilizzare @BeforeMethod e @AfterMethod ma questo è conveniente per me: sembra che non avrò bisogno di loro.

C'è un modo migliore per archiviare lo stesso effetto?

Ci scusiamo per il messaggio lungo.

Grazie in anticipo.

risposta

8

Puoi provare ad esplorare Factory in base alle tue esigenze. Factory ti consentirebbe di eseguire tutti i metodi annotati con @Test di una classe con dati diversi. In questo caso, puoi inizializzare il tuo webdriver. Spiegazione here.

+0

Grazie. Riuscito a fare esattamente quello che volevo. Inserita un'annotazione '@ Factory' sul costruttore e fatta ricevere dati dal fornitore di dati. Ogni istanza della classe di test ora rappresenta un driver Web connesso come un utente che sta eseguendo una serie di test. Il costruttore carica le proprietà e memorizza le credenziali utente specificate nei campi delle classi. Il metodo '@ BeforeClass' crea un'istanza del driver Web e accede con le credenziali memorizzate. '@ AfterClass' chiude il driver Web. Se qualcuno è interessato, il codice completo è qui. – yaromir

2

Okay, provami a rispondere alle tue domande sulla base della mia esperienza con testNG e webdriver.

D. Il @Test (dataProvider =) sulla classe indica qualcosa?
A. No. dataProvider è un'annotazione a livello di metodo e non a livello di classe. Come detto here. Dovrebbe essere un metodo che fornisce i dati per il metodo Test in formato Object [] [].

D. Come raggiungere lo scenario che hai menzionato? (Supponendo di aver compreso il tuo scenario ..)
A. Dovresti utilizzare @BeforeMethod anziché @BeforeClass per istanziare l'oggetto webdriver. In questo modo è possibile creare un oggetto WD diverso per ciascun metodo. E dataProvider può passare più dati al metodo isAuthenticated(). Se si desidera passare un file di configurazione a livello di classe, è possibile mantenere @BeforeClass con la logica di caricamento del file di proprietà. In questo modo il file delle proprietà verrà caricato una volta per l'intera classe. Ovviamente, dovresti usare anche @AfterMethod per chiudere l'oggetto webdriver.

+0

Grazie per la risposta. Stavo pensando a questa soluzione (idea №4), ma ho deciso che è inefficace perché è ridondante istanziare il driver Web e accedere prima di ogni metodo di test, perché, idealmente, è sufficiente farlo una volta per tutte metodi nella classe. Ho solo bisogno di eseguire tutte le azioni più volte con diverse istanze di web driver registrati come utenti diversi. Grazie comunque. Hai informazioni utili. – yaromir