Qual é a diferença entre as estruturas de teste de unidade ScalaTest e Scala Specs?


121

Ambos são estruturas de teste de unidade compatíveis com BDD (Behavior Driven Development) para Scala escritas em Scala. E Specs é construído sobre também pode envolver a estrutura ScalaTest . Mas o que as especificações oferecem ao ScalaTest não? Quais são as diferenças?


1
Não acredito que seja preciso dizer que o Specs foi desenvolvido com base no ScalaTest. Observe que a dependência no pom é opcional. No entanto, o Specs tem a capacidade de executar as especificações como um conjunto ScalaTest.
Geoff Reedy

O scalatest fornece ao scalatestplus suporte específico para várias bibliotecas. pode ser interessante. por exemplo, eles têm scalatestplus para enquadramento jogo
pedrorijo91

Respostas:


172

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 FeatureSpecsintaxe 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 GivenWhenThentraç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 isDirectorye 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 directoryou 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 classeSpecificationem 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 setUpe a tearDownabordagem 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 BeforeAndAftercaracterí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


6
A legibilidade do scalatest é um grande ponto de vitória sobre as especificações do scala para mim.
nemoo

49

As principais diferenças são (principalmente do ponto de vista das especificações :-)):

  • O ScalaTest fornece mais "estilos de teste" do que especificações (você pode visitar cada marcador na página de início rápido para obter uma visão detalhada de cada estilo)

  • O ScalaTest e as especificações têm um conjunto diferente de matchers. Você pode compará-los aqui para ScalaTest e aqui para especificações. Nesse aspecto, as especificações têm muitos recursos pequenos que você pode gostar ao escrever sua especificação: correspondências xml, composição de correspondências (uma maneira fácil de reutilizar correspondências, transformando-as), falhas precisas, diferenças detalhadas para seqüências longas .. .

  • O Mockito recebeu um bom suporte de BDD nas especificações: Mockito

  • O specs possui DataTables que permitem agrupar muitos exemplos pequenos em uma espécie de tabela (se você puder suportar operadores sendo usados ​​como delimitadores de tabela)

  • Nas especificações, você pode definir exemplos que são aninhados como libidum e limpos automaticamente em todos os níveis

Esta é certamente uma comparação muito parcial e tendenciosa e existem muitas outras diferenças (e as bibliotecas ainda estão evoluindo ...).

No final do dia, acho que realmente depende do seu estilo de teste / especificação. Se for simples (estrutura de especificação simples, configurações, expectativas, ...), as duas bibliotecas aparecerão muito semelhantes. Caso contrário, ambos têm uma opinião sobre como as coisas devem ser feitas. Como último exemplo, você pode dar uma olhada na marcação: no ScalaTest e nas especificações .

Eu espero que isso ajude.


Seria possível atualizar isso para cobrir as especificações2? :)
Joffer 4/15

5

Tanto quanto eu sei, com exceção de alguns recursos altamente especializados, tudo se resume à preferência pessoal de acordo com o estilo.


2

O suporte ao IDE pode ser outro ponto

Eu tenho tentado fazer com que o Specs funcione com o Eclipse através do JUnit, e achei a solução oficial um pouco "hacky". Configuração de especificações: http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse

A integração do ScalaTest (também através do JUnit) com parece um pouco menos invasiva. Ainda assim, não tenho nenhum deles para funcionar tão bem quanto JUnit e Java.

Configuração do ScalaTest: http://groups.google.com/group/scalatest-users/web/running-scalatest-from-eclipse


Eu recebo um 404 para esse link ScalaTest agora. Tente scalatest.org/user_guide/using_junit_runner
DNA

0

Se um fator de decisão é o tempo de compilação, o escalonamento parece ter um desempenho melhor.

No momento, estamos usando specs2 em nosso projeto, mas sofrem com tempos de compilação lentos nos testes. Acabei de concluir um POC ao passar para o escalatest e vi os tempos de compilação caírem em um fator de cerca de 0,82 apenas alternando as duas estruturas em algumas de nossas fontes.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.