Especificações e ScalaTest são boas ferramentas para usuários felizes, mas diferem de várias maneiras. Você provavelmente desejará escolher um como sua principal ferramenta de teste no Scala, mas não precisará desistir do outro, pois poderá usar partes de ambos. Se você gosta da FeatureSpec
sintaxe do ScalaTest e da sintaxe Mockito das especificações, por exemplo, pode colocar os dois arquivos jar no caminho da classe e usá-los ao mesmo tempo. Aqui, tentarei capturar as principais diferenças na filosofia de design que notei entre as especificações e o ScalaTest.
Provavelmente, a principal diferença filosófica entre as ferramentas é que as especificações são projetadas para o BDD (Behavior-Driven Development), enquanto o ScalaTest é mais geral. O ScalaTest fornece características que você pode misturar para obter o comportamento de sua preferência nas suas aulas de teste, incluindo o BDD, e também pode definir facilmente seu próprio comportamento, se desejar algo diferente.
ScalaTest suportes BDD através da sua Spec
, FeatureSpec
, WordSpec
, FlatSpec
, e GivenWhenThen
traços, e também tem características que você pode misturar para obter uma sintaxe de correspondência agradável. Se você gosta de "should", mistura os ShouldMatchers. Se você gosta de "must", você mistura MustMatchers
. Mas se você gosta de BDD, mas não gosta de sintaxe de correspondência, basta usar uma das características Spec do ScalaTest sem misturar a característica de correspondência. Specs tem uma classe Specification que você estende e deve usar a palavra "must" em suas expressões correspondentes. Uma grande diferença filosófica evidente aqui é que o ScalaTest oferece muito mais opções. Para facilitar a navegação desse espaço de escolha, forneço uma árvore de decisão aqui:
http://www.scalatest.org/quick_start
A sintaxe do correspondente também é diferente entre o ScalaTest e as especificações. No ScalaTest, tentei ver até onde podia ir com a notação do operador e acabei com expressões de correspondência que se pareciam muito com sentenças em inglês, com espaços entre as palavras. A sintaxe do combinador de especificações reúne as palavras mais com a caixa de camelo.
O Specs tem mais combinações que o ScalaTest, e acho que isso reflete uma diferença na atitude do design. Na verdade, cortei provavelmente 2/3 da sintaxe do matcher que criei e considerei para lançamento. Adicionarei mais correspondências em versões futuras, mas queria ter certeza de que sabia que os usuários realmente queriam algo antes de adicioná-lo. No entanto, os correspondentes do ScalaTest incluem uma sintaxe dinâmica do correspondente da propriedade que ocupa parte dessa folga. Por exemplo, em Especificações, você pode escrever em java.io.File
:
file must beDirectory
Isso invocará o isDirectory
e garantirá que seja verdade. Atualmente, o ScalaTest não possui correspondências especiais java.io.Files
, mas no ScalaTest você pode usar uma verificação dinâmica como esta:
file must be a ('directory)
Sempre que você passar um símbolo depois be
, ele usará a reflexão para procurar (neste caso) um método ou campo chamado directory
ou um método chamado isDirectory
. Há também uma maneira de tornar isso estático, definindo um BePropertyMatcher
(que requer apenas 2 ou 3 linhas de código normalmente). Então, basicamente no ScalaTest, tento fornecer mais funcionalidades com menos API.
Outra diferença geral de atitude de design entre as especificações e o ScalaTest envolve conversões implícitas. Por padrão, você obtém apenas uma conversão implícita ao usar o ScalaTest, que é o que coloca o ===
operador em tudo. (Se você precisar, pode "desativar" essa conversão implícita com uma linha de código. O único motivo para isso é se você estiver tentando testar algo que possui seu próprio ===
operador e tiver um conflito. ) O ScalaTest define muitas outras conversões implícitas, mas para usá-las, você precisa "convidá-las" explicitamente para o seu código, misturando uma característica ou fazendo uma importação. Quando você estende a classeSpecification
em especificações, acho que você recebe dezenas de conversões implícitas por padrão. Não tenho certeza do quanto isso importa na prática, mas acho que as pessoas vão querer testar o código que usa seus próprios implícitos, e às vezes pode haver um conflito entre os implícitos da estrutura de teste e os do código de produção. Quando isso acontece, acho que pode ser mais fácil solucionar o problema no ScalaTest do que as especificações.
Outra diferença na atitude de design que notei é o conforto dos operadores. Um objetivo que eu tinha era que qualquer programador que visse o código de teste de outra pessoa que usa o ScalaTest seria capaz de adivinhar qual era o significado sem procurar nada na documentação do ScalaTest. Eu queria que o código do cliente ScalaTest fosse óbvio. Uma maneira de o objetivo se manifestar é que o ScalaTest é muito conservador em relação aos operadores. Eu apenas defino cinco operadores no ScalaTest:
===
, o que significa igual
>
, o que significa maior que
<
, Menor que
>=
, maior ou igual
<=
, Menor ou igual.
É isso aí. Então, essas coisas parecem muito com o que significa. Se você vir o código de outra pessoa:
result should be <= 7
Minha esperança é que você não precise executar a documentação da API para adivinhar o que isso <=
significa. Por outro lado, as especificações são muito mais livres para os operadores. Nada de errado com isso, mas é uma diferença. Os operadores podem tornar o código mais conciso, mas a desvantagem é que você pode ter que executar a documentação quando você encontra coisas como ->-
, >>
, |
, |>
, !
, ou ^^^
(o que todos têm significados especiais em Specs) em código de teste do seu colega.
Outra diferença filosófica é que eu tento tornar um pouco mais fácil no ScalaTest usar um estilo funcional quando você precisa compartilhar um equipamento, enquanto o Specs por padrão continua a tradição setUp
e a tearDown
abordagem popularizada pela JUnit, na qual você reatribui vários antes de cada teste. No entanto, se você deseja testar dessa maneira, também é muito fácil no ScalaTest. Você só precisa misturar a BeforeAndAfter
característica.
Para mais informações sobre o ScalaTest, você pode assistir à apresentação "Get Higher with ScalaTest" que fiz na conferência Devoxx de 2009 aqui:
http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about