Il riutilizzo di Cetriolo passi

Voglio riutilizzare alcune Cetriolo passi, ma non riesco a trovare il modo giusto.

Voglio scrivere un passaggio come:

Given /^I login with (.*) credentials$/ |type|
  # do stuff with type being one of "invalid" or "valid"
end

Ma poi hanno un altro passo, come:

Given /^I login successfully$
  # call "Given I login with valid credentials"
end

Così nel test di autenticazione utente può utilizzare la ex, ma la maggior parte degli altri luoghi, posso usare l’ultimo, e in realtà non hanno a repro codice.

C’è un modo per chiamare altri, o ho appena messo la logica del metodo di supporto, e la chiamata di detto metodo da ogni attività (in pratica, un metodo di estrazione di refactoring, che, dopo aver letto la mia domanda mi fa credere che in realtà è il modo migliore comunque)?

  • Nel caso In cui qualcuno è confuso, qui tutti lasciando fuori il do necessaria per avviare il do...end blocco di Ruby fase di definizione. È, infatti, necessario.

 

5 Replies
  1. 101

    AGGIORNAMENTO: Il metodo descritto qui di seguito è stato deprecato. Il modo consigliato di chiamare un passo da un altro passo ora assomiglia a questo:

    Given /^I login successfully$/
        step "I login with valid credentials" 
    end 

    Vecchio, obsoleto metodo (per riferimento):

    È possibile chiamare i passaggi da altri passaggi come questo:

    Given /^I login successfully$/
      Given "I login with valid credentials"
      Then "I should be logged in"
    end

    Se tutti gli scenari all’interno di una caratteristica richiedono questo (o altri passaggi), è inoltre possibile aggiungere uno Sfondo per ogni funzionalità, con le operazioni più comuni, come:

    Background:
      Given I log in with valid credentials
    
    Scenario: Change my password
      Given I am on the account page
    • È ancora più facile incollare il cetriolino codice in questo modo: steps %Q{Given I am logged in}
    • Quando questa risposta è stata accettata, il steps metodo non esiste. Vedi la mia risposta qui sotto.
  2. 102

    Si noti che il metodo per la chiamata di procedura, a pochi passi è cambiato nelle versioni più recenti di cetriolo, di cui potrete vedere se si ottiene un errore del tipo “ATTENZIONE: l’Utilizzo di ‘Dato/Quando/Poi e’ in fase di definizioni è deprecato, utilizzare il ‘passaggio’ per chiamare altri passaggi invece:/path/to/step_definitions/foo_steps.rb:631:in `blocco’
    “. Vedere la cetriolo wiki per i dettagli.

    L’essenza del cambiamento è che ora si dovrebbe utilizzare il step o steps metodi.

    When /^I make all my stuff shiny$/
      step "I polish my first thing"
    end
    
    When /^I make all my stuff shiny$/
      steps %Q{
        When I polish my first thing
        When I shine my second thing
      }
    end
    • Per quello che vale, dopo più tempo con il Cetriolo, mi consiglia di non utilizzare i passaggi a pochi passi a tutti. I problemi sono difficili da rintracciare ed effettivamente rende la manutenzione più difficile. Invece, utilizzare metodi di supporto.
    • Forse, si dovrebbe includere questo commento nella vostra risposta in quanto con voto positivo e riceve ancora voti. Sarà aiutare le persone a notare queste informazioni
    • ciao @michaeltwofish, c’è qualche modifica a questo nel 2017? Sto diventando syntax error, unexpected tIDENTIFIER, expecting keyword_end stackoverflow.com/questions/43319331/…
  3. 42

    Chiamata procedura passaggio definizioni è una cattiva pratica e ha alcuni svantaggi:

    1. Se lo scenario avrà esito negativo e non ci sono nidificati passo invocazioni, si otterrà solo l’ultimo richiamato fase di definizione, l’analisi dello stack. Può essere difficile trovare da quale luogo che lo scorso stepdef è stato chiamato
    2. Chiamata a stepdef è a volte più difficile da trovare e leggere di ruby metodo
    3. Ruby metodi darà più potere rispetto alla chiamata di procedura dal passaggio defs

    Aslak Hellesøy consiglia per estrarre popolare azioni Mondo invece di riutilizzare i passaggi. Isola di tali azioni in un unico luogo, questo rende il codice più facile da trovare. È possibile estrarre il codice di solito Rubino classi o moduli.

    #/support/world_extensions.rb
    module KnowsUser
      def login
        visit('/login')
        fill_in('User name', with: user.name)
        fill_in('Password', with: user.password)
        click_button('Log in')
      end
    
      def user
        @user ||= User.create!(:name => 'Aslak', :password => 'xyz')
      end
    end
    World(KnowsUser)
    
    #/step_definitions/authentication_steps.rb
    When /^I login$/ do
      login
    end
    
    Given /^a logged in user$/ do
      login
    end

    Ecco una utile discussione sull’argomento in Cetriolo mailing list – link

    • Io credo che questo approccio è molto meglio rispetto alla chiamata di fase o nelle fasi funzioni per le stesse ragioni di cui sopra.
    • Questo è un altro vantaggio. Utilizza Idea (o Rubymine), si può facilmente passare alla funzione-definizioni, ma non per i passaggi passaggi di %{…}.
    • anche questo viene seguito LAVAGGIO principio
    • Anche se ho centrato il problema del riutilizzo dei passaggi, penso che questo sia il male. Il Login è solo la somma di diverse fasi: “visitare qualcosa di”, “riempire qualcosa”. Il modo naturale sarebbe il riutilizzo passi, invece di convertire ogni passo in una chiamata a una funzione. IMO, chiamando i passaggi all’interno di passaggi devono essere solo migliorata.
  4. 9

    Migliore di avvolgere i vostri passi in %{} invece di citazioni. Quindi, non c’è bisogno di fuggire tra doppie virgolette, è necessario utilizzare frequentemente.:

    Given /^I login successfully$
      step %{I login with valid credentials}
    end
    
    Given /^I login with (.*) credentials$/ |type|
      # do stuff with type being one of "invalid" or "valid"
    end
    • Questo doveva essere un commento invece di una risposta.
  5. 1

    Riutilizzare le parole chiave nella funzionalità di file che fornirà la riutilizzabilità del codice.

    NON è altamente raccomandato di chiamare passaggio defs all’interno di step defs.

    Vorrei scrivere la mia funzione di file in questo modo,

    Scenario Outline: To check login functionality
        Given I login with "<username>" and "<password>"
        Then I "<may or may not>" login successfully
    
    Examples:
        |username|password|may or may not|
        |paul    |123$    |may           |
        |dave    |1111    |may not       |

    Nella mia fase di definizione, (Questo è Java)

    @Given(I login with \"([^\"]*)\" and \"([^\"]*)\"$)
    public void I_login_with_and(String username, String password){
    
       //login with username and password
    
    }
    
    @Then(I \"([^\"]*)\" login successfully$)
    public void I_login_successully_if(String validity){
    
        if(validity.equals("may")){
            //assert for valid login
        }
        else
        if(validity.equals("may not")){
            //assert for invalid login
        }
    }

    In questo modo, c’è un sacco di riusabilità del codice.
    Il tuo stesso Dato e Poi gestisce sia valido e non valido scenari.
    Allo stesso tempo, il file di senso per i lettori.

Lascia un commento