Casuale nei test di accettazione

1

Ho una semplice soluzione di autenticazione, in cui un utente può accedere con e-mail o nome utente.

Dato che voglio mostrare la piccola funzionalità nei test di accettazione ma non voglio inquinarli, ho pensato di introdurre un po 'di casualità. Pensi che questo sia cattivo o buono?

step "Fill in my credentials" do
    fill_in :user_login, with: [@user.email, @user.name].sample
    fill_in :user_password, with: @user.password
end
    
posta wintersolutions 30.03.2013 - 01:28
fonte

4 risposte

2

Eviterei la casualità nei test automatici. Vuoi che tutti i tuoi test automatici siano prevedibili. Provare input casuali non è certamente prevedibile. In questo modo se uno dei tuoi test fallisce, sarai in grado di determinare più rapidamente il perché.

Invece, dedica del tempo a pensare a casi che potrebbero meritare di essere testati e testarli esplicitamente. Pensare al tuo codice in questo modo è più efficace dell'usare test casuali e sperare che catturino casi a cui non avevi pensato.

    
risposta data 30.03.2013 - 02:13
fonte
7

Supponiamo che funzioni per email, ma non per nome.

Ora il test di accettazione fallirà metà del tempo. Solo rieseguire il test cambierà potenzialmente il risultato. Ciò renderà più difficile notare gli errori e rintracciare il problema con esso si verifica. Sarà molto più semplice se scrivi solo due test, uno per ciascun metodo di accesso.

    
risposta data 30.03.2013 - 03:02
fonte
2

Non dirò che la casualità è una cattiva idea.

[Sav07] ha testato l'implementazione dell'algoritmo per la ricerca binaria scrivendo un gruppo di test che includeva alcune "teorie" (ipotesi) su come l'algoritmo di ricerca doveva eseguire.

Quindi ha eseguito il gruppo "completo" di test con un sacco di proiettori casuali.

In Ruby:

require "test/unit"
require "binary_search" # binary_search gem: 
                        # <https://github.com/tyler/binary_search>

class BinarySearchTestTheories < Test::Unit::TestCase
    def before_all
       @rand = Random.new()
    end

    def test_theories
        experiments = 1000
        max_value = 1073741824 # Fixnum max value

        while (experiments-- > 0) do
            test_array = generateRandomSortedArray

            target_must_exist = [true, false].sample
            if target_must_exist
                target = test_array[@rand.rand(test_array.length)]
            elsif
                target = @rand.integer(max_value)
            end

            return_value = test_array.binary_search { |v| target <=> v }

            assert_theory1(test_array, target, return_value)
            assert_theory2(test_array, target, return_value)
            assert_theory3(test_array, target, return_value)
            assert_theory4(test_array, target, return_value)
        end
    end

    # Theories
    def assert_theory1(arr, target, expectation) ... end
    def assert_theory2(arr, target, expectation) ... end
    def assert_theory3(arr, target, expectation) ... end
    def assert_theory4(arr, target, expectation) ... end

    # Helper
    def does_array_contain_target?(arr, target) ... end
    def target_position(arr, target) ... end
end

Non sono sicuro che le sue "teorie sui test" si qualificano come test di accettazione, ma sono chiaramente al di là dei test unitari o di "limite".

La mia conclusione: i test di accettazione casuale sono utili per algoritmi prevedibili. Le e-mail di campionamento e le impostazioni dei nomi utente sembrano abbastanza banali.

[Sav07] Alberto Savoia: "Beautiful Tests", in: Andy Oram e Greg Wilson (a cura di): Beautiful Code , Beijing: O'Reilly, 2007.

Vedi l'articolo completo all'indirizzo: link

    
risposta data 30.04.2013 - 09:07
fonte
1

A volte scrivo test che dipendono da occorrenze casuali per sapere se hanno successo o meno. Ho imparato che ci sono alcune avvertenze, come descritto da altre risposte:

  • Non preferisci un test che a volte fallisce. Se si interrompe il codice, si desidera scoprire quando si integra la modifica, in modo da sapere quale modifica annullare.
  • Se c'è solo un piccolo numero di input che causano errori, è necessario sapere quali input sono per risolvere il problema.

Il primo problema può essere risolto per lo più, a patto che si desideri accettare una suite di test lenta, eseguendo il test più volte. Quest'ultimo problema richiede di registrare tutti i fattori casuali che potrebbero causare l'errore.

Queste tecniche si applicano anche a situazioni in cui la casualità è inevitabile, ad es. stai testando le potenziali condizioni relative ai tempi in un programma multithread.

Finché stai attento, può essere fatto. Ma la cosa migliore da fare è isolare potenziali condizioni di guasto e scrivere un test prevedibile che fallisce sempre per loro prima di risolvere il problema, IMHO.

    
risposta data 30.03.2013 - 10:33
fonte

Leggi altre domande sui tag