Domanda

Sto espandendo la mia comprensione di Ruby codificando un equivalente della xUnit di Kent Beck in Ruby. Python (in cui Kent scrive) ha un metodo assert () nel linguaggio che viene ampiamente utilizzato. Ruby no. Penso che dovrebbe essere facile aggiungere questo, ma Kernel è il posto giusto per dirlo?

A proposito, So dell'esistenza dei vari framework Unit in Ruby - questo è un esercizio per imparare gli idiomi di Ruby, piuttosto che "fare qualcosa".

È stato utile?

Soluzione

No, non è una buona pratica. La migliore analogia da asserire () in Ruby sta solo aumentando

 raise "This is wrong" unless expr

e puoi implementare le tue eccezioni se desideri fornire una gestione delle eccezioni più specifica

Altri suggerimenti

Penso che sia assolutamente valido usare assert in Ruby. Ma stai citando due cose diverse:

  • I framework xUnit utilizzano i metodi assert per verificare le aspettative dei test. Devono essere utilizzati nel codice di test, non nel codice dell'applicazione.
  • Alcuni linguaggi come C, Java o Python, includono una costruzione assert destinata ad essere utilizzata all'interno del codice dei programmi, per verificare le ipotesi formulate in merito alla loro integrità. Questi controlli sono integrati nel codice stesso. Non sono un'utilità in fase di test, ma in fase di sviluppo.

Di recente ho scritto solid_assert: una piccola libreria di Ruby che implementa un'utilità di asserzione di Ruby e anche un post nel mio blog che spiega la sua motivazione .. Lascia scrivi espressioni nel formato:

assert some_string != "some value"
assert clients.empty?, "Isn't the clients list empty?"

invariant "Lists with different sizes?" do
    one_variable = calculate_some_value
    other_variable = calculate_some_other_value
    one_variable > other_variable
end    

E possono essere disattivati ??in modo che asserisci e invariant vengano valutati come istruzioni vuote. Ciò consente di evitare qualsiasi problema di prestazioni in produzione. Tuttavia, I programmatori pragmatici sconsigliano di disattivarli. Dovresti disattivarli solo se incidono davvero sulla performance.

Per quanto riguarda la risposta che dice che il modo Rubi idiomatico sta usando una normale istruzione raise , penso che manchi di espressività. Una delle regole d'oro della programmazione assertiva non è l'uso delle asserzioni per la normale gestione delle eccezioni. Sono due cose completamente diverse. Se usi la stessa sintassi per entrambi, penso che il tuo codice sarà più oscuro. E ovviamente perdi la capacità di disattivarli.

Puoi essere convinto che usare le asserzioni sia una buona cosa perché due libri classici da leggere come The Pragmatic Programmer From Journeyman to Master e Codice completo dedica tutto sezioni a loro e raccomandarne l'uso. C'è anche un bell'articolo intitolato Programmazione con asserzioni che illustra molto bene la programmazione assertiva e quando usarla (è basata su Java, ma i concetti si applicano a qualsiasi linguaggio).

Qual è il motivo per cui hai aggiunto il metodo assert al modulo Kernel? Perché non usare semplicemente un altro modulo chiamato Assertions o qualcosa del genere?

In questo modo:

module Assertions
  def assert(param)
    # do something with param
  end

  # define more assertions here
end

Se hai davvero bisogno che le tue affermazioni siano disponibili ovunque fai qualcosa del genere:

class Object
  include Assertions
end

Disclaimer: non ho testato il codice ma in linea di principio lo farei così.

Non è particolarmente idiomatico, ma penso sia una buona idea. Soprattutto se fatto così:

def assert(msg=nil)
    if DEBUG
        raise msg || "Assertion failed!" unless yield
    end
end

In questo modo non ha alcun impatto se decidi di non eseguire DEBUG (o qualche altro comodo switch, ho usato Kernel.do_assert in passato) set.

La mia comprensione è che stai scrivendo la tua suite di test come un modo per familiarizzare con Ruby. Quindi, mentre Test :: Unit potrebbe essere utile come guida, probabilmente non è quello che stai cercando (perché ha già fatto il lavoro).

Detto questo, l'affermazione di Python è (almeno per me) più analoga a quella di C affermare (3) . Non è specificamente progettato per test unitari, piuttosto per individuare casi in cui "ciò non dovrebbe mai accadere".

In che modo i test unitari integrati di Ruby tendono a visualizzare il problema, quindi, è che ogni singola classe di test case è una sottoclasse di TestCase , e che include un" assert " dichiarazione che verifica la validità di ciò che gli è stato passato e lo registra per la segnalazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top