Qual è la differenza tra i framework di unit test ScalaTest e Scala Specs?


121

Entrambi sono framework di unit test capaci di BDD (Behaviour Driven Development) per Scala scritti in Scala. E le specifiche su cui si basa possono anche coinvolgere il framework ScalaTest . Ma cosa offre le specifiche che ScalaTest non offre? Quali sono le differenze?


1
Non credo che sia corretto dire che Specs è basato su ScalaTest. Nota che la dipendenza nel pom è facoltativa. Tuttavia, le specifiche possono essere eseguite come una suite ScalaTest.
Geoff Reedy

scalatest fornisce scalatestplus con supporto specifico per diverse librerie. potrebbe essere interessante. ad esempio, hanno scalatestplus per il framework di gioco
pedrorijo91,

Risposte:


172

Specifiche e ScalaTest sono entrambi buoni strumenti con utenti soddisfatti, ma differiscono in diversi modi. Probabilmente vorrai sceglierne uno come strumento di test principale in Scala, ma non devi rinunciare all'altro perché puoi usare parti di entrambi. Se ti piace la FeatureSpecsintassi di ScalaTest e la sintassi Mockito delle specifiche, ad esempio, puoi inserire entrambi i file jar nel tuo classpath e usarli entrambi allo stesso tempo. Qui cercherò di catturare le principali differenze di filosofia di progettazione che ho notato tra le specifiche e ScalaTest.

Probabilmente la principale differenza filosofica tra gli strumenti è che le specifiche sono progettate per lo sviluppo guidato dal comportamento (BDD), mentre ScalaTest è più generale. ScalaTest fornisce tratti che puoi mescolare insieme per ottenere il comportamento che preferisci nelle tue classi di test, incluso BDD, e puoi anche definire facilmente il tuo comportamento se vuoi qualcosa di diverso.

ScalaTest supporti BDD attraverso la sua Spec, FeatureSpec, WordSpec, FlatSpec, e GivenWhenThentratti, e ha anche caratteristiche che si possono mescolare per ottenere un bel sintassi matcher. Se ti piace "dovrebbe", mescola ShouldMatchers. Se ti piace il "must", mischia MustMatchers. Ma se ti piace BDD ma non ti piace la sintassi del matcher, puoi semplicemente usare uno dei tratti Spec di ScalaTest senza mescolare un tratto del matcher. Specs ha una classe Specification che estendi e devi usare la parola "must" nelle espressioni del matcher. Una grande differenza filosofica che è evidente qui è che ScalaTest ti offre molte più scelte. Per rendere questo spazio di scelta più facile da navigare, fornisco un albero decisionale qui:

http://www.scalatest.org/quick_start

Anche la sintassi del matcher è diversa tra ScalaTest e specs. In ScalaTest ho cercato di vedere fino a che punto potevo andare con la notazione degli operatori, e sono finito con espressioni di corrispondenza che si leggono in modo molto simile alle frasi inglesi, con spazi tra le parole. La sintassi di corrispondenza delle specifiche esegue le parole insieme più con il caso del cammello.

Specs ha più matcher di ScalaTest e penso che rifletta una differenza nell'attitudine al design. In realtà ho tagliato probabilmente 2/3 della sintassi del matcher che ho costruito e preso in considerazione per il rilascio. Aggiungerò più abbinamenti nelle versioni future, ma volevo essere sicuro di sapere che gli utenti volevano effettivamente qualcosa prima di aggiungerlo. Tuttavia, i matcher di ScalaTest includono una sintassi del matcher di proprietà dinamico che occupa parte di quel margine di flessibilità. Ad esempio in Specifiche puoi scrivere su java.io.File:

file must beDirectory

Questo richiamerà il isDirectorye si assicurerà che sia vero. ScalaTest non ha abbinamenti speciali per il java.io.Filesmomento, ma in ScalaTest, potresti semplicemente usare un controllo dinamico come questo:

file must be a ('directory)

Ogni volta che si passa un simbolo dopo be, utilizzerà la riflessione per cercare (in questo caso) un metodo o un campo denominato directoryo un metodo denominato isDirectory. C'è anche un modo per renderlo statico, definendo a BePropertyMatcher(che di solito richiede solo 2 o 3 righe di codice). Quindi fondamentalmente in ScalaTest cerco di fornire più funzionalità con meno API.

Un'altra differenza nell'atteggiamento di progettazione generale tra le specifiche e ScalaTest riguarda le conversioni implicite. Per impostazione predefinita, ottieni una sola conversione implicita quando usi ScalaTest, che è quella che mette l' ===operatore su tutto. (Se necessario, puoi "disattivare" questa conversione implicita con una riga di codice. L'unico motivo per cui dovresti farlo è se stavi provando a testare qualcosa che ha il suo ===operatore e ottieni un conflitto. ) ScalaTest definisce molte altre conversioni implicite, ma per usarle è necessario "invitarle" esplicitamente nel codice mescolando un tratto o eseguendo un'importazione. Quando estendi la classeSpecificationnelle specifiche penso che tu ottenga praticamente dozzine di conversioni implicite per impostazione predefinita. Non sono sicuro di quanto sarà importante nella pratica, ma immagino che le persone vorranno testare il codice che utilizza i propri impliciti e talvolta potrebbe esserci un conflitto tra gli impliciti del framework di test e quelli del codice di produzione. Quando ciò accade, penso che potrebbe essere più facile aggirare il problema in ScalaTest rispetto alle specifiche.

Un'altra differenza nell'attitudine al design che ho notato è il comfort con gli operatori. Uno degli obiettivi che avevo era che qualsiasi programmatore che guardasse il codice di test di qualcun altro che usa ScalaTest sarebbe in grado di indovinare quale fosse il significato senza cercare nulla nella documentazione di ScalaTest. Volevo che il codice client ScalaTest fosse ovvio. Un modo in cui l'obiettivo si è manifestato è che ScalaTest è molto conservatore riguardo agli operatori. Definisco solo cinque operatori in ScalaTest:

  • ===, che significa uguale
  • >, che significa maggiore di
  • <, meno di
  • >=, Maggiore o uguale
  • <=, minore o uguale.

Questo è tutto. Quindi queste cose sembrano più o meno quello che significano. Se vedi nel codice di qualcun altro:

result should be <= 7

La mia speranza è che non sia necessario eseguire la documentazione dell'API per indovinare cosa <=significa. Al contrario, le specifiche sono molto più libere con gli operatori. Non c'è niente di sbagliato in questo, ma è una differenza. Gli operatori possono rendere il codice più conciso, ma il compromesso è che si potrebbe essere necessario eseguire la documentazione quando si trova cose come ->-, >>, |, |>, !, o ^^^(che hanno tutti un significato speciale in Spec) nel codice di prova del vostro collega.

Un'altra differenza filosofica è che cerco di rendere leggermente più semplice in ScalaTest utilizzare uno stile funzionale quando è necessario condividere un dispositivo, mentre Specs per impostazione predefinita continua la tradizione dell'approccio setUpe tearDownreso popolare da JUnit, in cui si riassegnano i vars prima di ogni prova. Tuttavia, se vuoi testare in questo modo, è anche molto semplice in ScalaTest. Hai solo bisogno di mescolare il BeforeAndAftertratto.

Per ulteriori informazioni su ScalaTest, puoi guardare la presentazione "Get Higher with ScalaTest" che ho tenuto alla conferenza Devoxx del 2009 qui:

http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about


6
La leggibilità di scalatest è per me un importante punto vincente rispetto alle specifiche di scala.
nemoo

49

Le principali differenze sono (principalmente dal punto di vista delle specifiche :-)):

  • ScalaTest fornisce più "stili di test" rispetto alle specifiche (puoi visitare ogni punto elenco nella pagina di avvio rapido per ottenere una visualizzazione dettagliata di ogni stile)

  • ScalaTest e specs hanno un diverso set di matcher. Puoi confrontarli qui per ScalaTest e qui per le specifiche. Da quel punto di vista, le specifiche hanno molte piccole funzionalità che potrebbero piacerti quando scrivi la tua specifica: corrispondenze xml, composizione di abbinamenti (un modo semplice per riutilizzare i corrispondenze trasformandoli), errori precisi, differenze dettagliate per stringhe lunghe, .. .

  • Mockito ha ricevuto un bel supporto BDD nelle specifiche: Mockito

  • specs ha DataTables che consentono di raggruppare molti piccoli esempi in una sorta di tabella (se puoi sopportare gli operatori utilizzati come delimitatori di tabella)

  • Nelle specifiche è possibile definire esempi annidati come libidum e ripuliti automaticamente a ogni livello

Questo è certamente un paragone molto parziale e parziale e esistono molte altre differenze (e le biblioteche sono ancora in evoluzione, ...).

Alla fine della giornata penso che dipenda davvero dal tuo stile di test / specificazione. Se è semplice (semplice struttura delle specifiche, impostazioni, aspettative, ...) allora entrambe le librerie appariranno molto simili. Altrimenti, entrambi hanno la loro opinione su come dovrebbero essere fatte le cose. Come ultimo esempio di questo puoi dare un'occhiata al tagging: in ScalaTest e in specs .

Spero che aiuti.


Sarebbe possibile aggiornarlo per coprire le specifiche2? :)
Joffer

5

Per quanto ne so, salvo alcune caratteristiche altamente specializzate, dipende dalle preferenze personali in base allo stile.


2

Il supporto IDE potrebbe essere un altro punto

Ho cercato di far funzionare Specs con Eclipse tramite JUnit e ho trovato la soluzione ufficiale un po '"hacky". Configurazione delle specifiche: http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse

L'integrazione di ScalaTest (anche tramite JUnit) con sembra un po 'meno hacky. Tuttavia, non ne ho nessuno per funzionare bene come JUnit e Java.

Configurazione di ScalaTest: http://groups.google.com/group/scalatest-users/web/running-scalatest-from-eclipse


Ora ottengo un 404 per quel collegamento ScalaTest. Prova scalatest.org/user_guide/using_junit_runner
DNA

0

Se un fattore decisionale è il tempo di compilazione, scalatest sembra funzionare meglio.

Attualmente stiamo usando specs2 nel nostro progetto, ma soffriamo di tempi di compilazione lenti nei test. Ho appena terminato un POC sul passaggio a scalatest e ho visto i tempi di compilazione diminuire di un fattore di circa 0,82 semplicemente cambiando i 2 framework in alcuni dei nostri sorgenti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.