16

Stiamo pensando di utilizzare Cetriolo sul nostro progetto per il test di accettazione.Come organizzare la definizione delle specifiche in Cetriolo?

Quando scriviamo un scenario in un cetriolo feature, scriviamo un elenco di Given, When e Then dichiarazioni.

Come usiamo cucumber-jvm progetto, la dichiarazione Given, When e Then sono legati a metodi Java in (JUnit) classi.

Desidero sapere qual è la migliore organizzazione per il codice relativo a Given/When/Then nella struttura del progetto. La mia preoccupazione principale è il mantenimento dei test di cetriolo su un grande progetto, in cui il numero di scenari è piuttosto importante, e in particolare per quanto riguarda gli elementi condivisi tra le funzionalità.

posso vedere almeno 2 approcci principali:

  1. Ogni funzione è legata ad essa la propria classe di JUnit. Quindi, se ho un file cetriolo foo/bar/baz.feature, troverò la classe JUnit foo.bar.Baz con i metodi adeguati @Given, @When e @Then annotato.

  2. Separare i metodi @Given, @When e @Then in classi e pacchetti "tematici". Ad esempio, se nel mio scenario cetriolo ho una dichiarazione Given user "foo" is logged, il metodo annotato @Given("^user \"([^\"]*)\" is logged$") si troverà nel metodo di classe foo.user.User, ma potenzialmente il metodo @When utilizzato successivamente nello stesso scenario cetriolo sarà in una classe e pacchetto Java diversi (diciamo foo.car.RentCar).

Per me, il primo approccio sembra buona in modo che io possa fare facilmente il rapporto tra le mie caratteristiche di cetriolo e il mio codice Java. Ma l'inconveniente è che posso avere un sacco di ridondanze o di duplicazione del codice. Inoltre, potrebbe essere difficile trovare un possibile metodo esistente @Given, per evitare di ricrearlo (l'IDE può aiutare, ma qui stiamo usando Eclipse, e non sembra fornire un elenco di dichiarazioni esistenti Given?).

L'altro approccio sembra meglio essenzialmente quando si dispone di Given condizioni condivisi tra più caratteristica cetriolo, e, quindi, voglio evitare la duplicazione del codice. Lo svantaggio qui è che può essere difficile stabilire il collegamento tra il metodo Java @Given e l'istruzione cetriolo Given (forse, di nuovo, l'IDE può aiutare?).

Sono abbastanza nuovo per il cetriolo, quindi forse la mia domanda non è una buona domanda, e con il tempo e l'esperienza, la struttura sarà ovvia, ma voglio ricevere feedback positivi sul suo utilizzo ...

Grazie.

+0

Nota che non penso sia un duplicato di questa domanda: http://stackoverflow.com/questions/5023128/cucumber-how-to-organize-a-complex-test-set – romaintaz

risposta

1

Abbiamo anche iniziato a utilizzare Cucumber-JVM per i test di accettazione e abbiamo problemi simili con l'organizzazione del codice. Abbiamo optato per la classe di definizione 1 passo per ogni funzione. Al momento questo va bene, dato che le funzionalità che stiamo testando non sono molto complesse e piuttosto separate, c'è una piccola sovrapposizione nelle nostre funzionalità.

Il secondo approccio che hai menzionato sarebbe meglio, credo, ma è spesso difficile mettere insieme diverse classi di definizione dei passaggi per un singolo scenario. Penso che la migliore struttura del progetto diventerà più chiara una volta che inizierai ad aggiungere più funzioni e refactor come di consueto.

Nel frattempo qui è un plugin Eclipse per cetrioli,

https://github.com/matthewpietal/Eclipse-Plugin-for-Cucumber

ha l'evidenziazione della sintassi, nonché un elenco di passaggi disponibili esistenti quando si scrive una funzione.

+0

Grazie. Sto già usando il plug-in di Eclipse, ma non sono ancora molto soddisfatto (ma può essere migliorato, ovviamente) – romaintaz

+0

Avresti la possibilità di passare a IntelliJ (c'è una versione gratuita della community); è molto utile nel suggerire StepDefinitions esistenti. – Marit

2

Suggerirei di raggruppare il codice in base agli oggetti a cui fa riferimento, in modo simile all'opzione 2 che hai presentato nella domanda. Le ragioni che sono:

  • Strutturare il codice in base a come e dove è in uso è un grande no-no. In realtà sta creando un accoppiamento tra i tuoi file di funzione e il tuo codice.
    Immaginate una cosa del genere nel codice del vostro prodotto: la funzione SendEmail() non si troverà in una classe chiamata NewEmailScreenCommands, vero? Sarebbe nel EmailActions o alcuni di questi.
    Quindi lo stesso vale qui; struttura il tuo codice in base a ciò che fa e non a chi lo usa.

  • Il primo approccio renderebbe difficile la riorganizzazione dei file delle funzionalità; Dovresti cambiare i tuoi file di codice ogni volta che cambi i file delle caratteristiche.

  • Mantenere il codice raggruppato per tema rende l'ASCIUGATURA molto più semplice; sai esattamente dove si trova tutto il codice che si occupa dell'entità user, quindi è più facile riutilizzarlo.

Sul nostro progetto abbiamo utilizzare questo approccio (cioè BlogPostStepDefinitions classe), con separazione ulteriormente il codice, se la classe diventa troppo grande, per i tipi di operazioni (cioè BlogPostGivenStepDefinitions).

0

Sul progetto in corso a cui partecipo, ci siamo posti la stessa domanda.

Dopo aver giocherellato un po 'con le possibilità, ciò che abbiamo optato per è stato un mix di entrambe le soluzioni che hai esposto.

  • avere gradini raggruppati in classi fasi comuni a tema incentrato
    • app-inizio passaggi
    • controllo di sicurezza i passaggi
    • [caratteristica casuale posto preoccupazione qui] i passi
  • e classi dello scenario (e in alcuni casi anche della funzionalità) passi specifici

Questo doveva avere allo stesso tempo il raggruppamento di codice fattorizzato che è abbastanza facilmente identificabile in merito a dove, dove e altro. Eppure consente di non ingombrare quelle classi comuni con codice troppo specifico.

Il cablaggio tra tutte queste classi è gestito dalla primavera (con molla di cetriolo che fa un ottimo lavoro una volta che si ottiene il blocco di esso).