<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mario Rezende</title>
    <description>The latest articles on DEV Community by Mario Rezende (@mariorez).</description>
    <link>https://dev.to/mariorez</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3149%2Ff617f089-a60f-4348-8284-2f838b956fc2.jpg</url>
      <title>DEV Community: Mario Rezende</title>
      <link>https://dev.to/mariorez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mariorez"/>
    <language>en</language>
    <item>
      <title>Spock Framework: Teste Java com mais produtividade</title>
      <dc:creator>Mario Rezende</dc:creator>
      <pubDate>Wed, 15 Jan 2020 03:13:17 +0000</pubDate>
      <link>https://dev.to/mariorez/spock-framework-teste-java-com-mais-produtividade-4ibn</link>
      <guid>https://dev.to/mariorez/spock-framework-teste-java-com-mais-produtividade-4ibn</guid>
      <description>&lt;p&gt;Quem já escreve testes há algum tempo deve ter percebido que, para cada funcionalidade da aplicação que queremos testar, temos que escrever ao menos um cenário que cobre o “caminho feliz” e um ou mais cenários que cobrem os “caminhos infelizes”. Escrevemos muito mais código na suíte de testes em comparação ao código que será executado de fato em produção.&lt;/p&gt;

&lt;p&gt;Tendo isso em vista, a ferramenta que utilizamos para dar suporte a criação de testes têm impacto significativo na velocidade de desenvolvimento, manutenção e evolução da aplicação.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caminho feliz&lt;/strong&gt;: cenário onde o cliente utiliza a aplicação de acordo com as especificações do projeto.&lt;br&gt;
&lt;strong&gt;Caminho infeliz&lt;/strong&gt;: são as possibilidades de utilização incorretas da aplicação pelo cliente (exceções).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neste artigo vou apresentar o &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html"&gt;&lt;strong&gt;Spock&lt;/strong&gt;&lt;/a&gt;, um framework de &lt;strong&gt;testes&lt;/strong&gt; para aplicações &lt;strong&gt;Java&lt;/strong&gt; e &lt;strong&gt;Groovy&lt;/strong&gt;, e como sua linguagem de especificação elegante e expressiva pode trazer maior produtividade no dia-a-dia do programador.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analisaremos o Spock através das seguintes características:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Legibilidade e organização do teste&lt;/li&gt;
&lt;li&gt;  Versatilidade de parametrização do teste&lt;/li&gt;
&lt;li&gt;  Reportando falhas&lt;/li&gt;
&lt;li&gt;  Testando a interação entre objetos: “&lt;em&gt;Mocking&lt;/em&gt;” e “&lt;em&gt;Stubbing&lt;/em&gt;”&lt;/li&gt;
&lt;li&gt;  Trabalhando com exceções&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Legibilidade e organização do teste
&lt;/h2&gt;

&lt;p&gt;Praticamente todo teste que escrevemos (salvo algumas exceções) seguem as seguintes &lt;a href="http://xunitpatterns.com/Four%20Phase%20Test.html"&gt;fases&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Configuração&lt;/strong&gt;: onde inicializamos os dados que utilizaremos no teste.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Execução&lt;/strong&gt;: onde o objeto que está sendo testado será executado.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Verificação&lt;/strong&gt;: onde avaliamos os resultados retornados na fase de execução.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vamos exemplificar essas fases escrevendo um cenário que testará uma funcionalidade fictícia de cadastro de usuário com &lt;a href="https://junit.org/junit5/"&gt;JUnit 5&lt;/a&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Embora essas fases estejam presentes na maioria dos testes, nem todas as bibliotecas dispoẽm de mecanismos para deixar isso de forma explícita; no caso do JUnit costumo usar comentários para demarcar cada fase.&lt;/p&gt;

&lt;p&gt;Reescrevendo esse mesmo cenário com o Spock o teste fica bem mais legível e organizado, graças a linguagem &lt;a href="http://groovy-lang.org/"&gt;Groovy&lt;/a&gt; (base do Spock) que nos permite escrever os métodos de &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_feature_methods"&gt;forma declarativa&lt;/a&gt; e manter o corpo do teste mais simples e conciso. O Spock impõe a separação das fases ao estilo &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development"&gt;BDD&lt;/a&gt;, utilizando os &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_blocks"&gt;blocos&lt;/a&gt;: “&lt;strong&gt;&lt;em&gt;given&lt;/em&gt;&lt;/strong&gt;”, “&lt;strong&gt;&lt;em&gt;when&lt;/em&gt;&lt;/strong&gt;” e “&lt;strong&gt;&lt;em&gt;then&lt;/em&gt;&lt;/strong&gt;”.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;A fase de verificação também fica mais simples, pois utiliza os mesmos operadores de comparação do Java (removendo a necessidade de conhecer os métodos de “&lt;a href="https://junit.org/junit5/docs/current/user-guide/#writing-tests-assertions"&gt;&lt;em&gt;assertion&lt;/em&gt;&lt;/a&gt;”):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Dica&lt;/strong&gt;: existe também o bloco “&lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt;” que pode ser usado para deixar a &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#specifications_as_documentation"&gt;especificação&lt;/a&gt; do teste mais compreensível:&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Versatilidade de parametrização do teste
&lt;/h1&gt;

&lt;p&gt;Com frequência precisamos executar o teste com dados diferentes para garantir que todos os cenários possíveis estão sendo validados.&lt;/p&gt;

&lt;p&gt;O Spock resolve esse problema através do bloco “&lt;em&gt;where&lt;/em&gt;” onde podemos prover uma lista de dados a serem utilizados em nossos testes.&lt;/p&gt;

&lt;p&gt;No exemplo abaixo utilizamos o “&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#data-tables"&gt;&lt;em&gt;Data Tables&lt;/em&gt;&lt;/a&gt;” para fornecer os dados de entrada ao método do teste. A primeira linha da tabela (&lt;em&gt;header&lt;/em&gt;) declara o nome das variáveis que utilizaremos no teste, e as demais linhas correspondem ao valor dessas variáveis. Para cada linha o método do teste será executado uma vez.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Organizando os dados no formato de tabela facilita tanto para quem escreve, como também para quem lê o teste; fazendo com que o teste sirva como uma documentação do funcionamento do objeto sob teste.&lt;/p&gt;

&lt;p&gt;O Spock utiliza o conceito de “&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_data_driven_testing"&gt;&lt;em&gt;Data Driven Testing&lt;/em&gt;&lt;/a&gt;”, que fornece diversas formas de gerarmos dados de entrada, dando mais flexibilidade ao programador durante a escrita dos testes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#data-tables"&gt;Data Tables&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_data_pipes"&gt;Data Pipes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_multi_variable_data_pipes"&gt;Multi-Variable Data Pipes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_data_variable_assignment"&gt;Data Variable Assignment&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_combining_data_tables_data_pipes_and_variable_assignments"&gt;Combinação dos itens acima&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Reportando falhas
&lt;/h1&gt;

&lt;p&gt;No teste abaixo inserimos uma falha propositalmente na tabela do bloco “where” (linha 9):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Dica&lt;/strong&gt;: prefira utilizar o bloco “&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_expect_blocks"&gt;&lt;em&gt;expect&lt;/em&gt;&lt;/a&gt;” quando a execução e a validação podem ser descritas numa única fase.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ao executar o teste teremos a seguinte saída no terminal:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Com Spock é fácil de identificar que a falha ocorreu na segunda interação, mas podemos deixar essa informação ainda mais explícita utilizando a anotação de “&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_method_unrolling"&gt;@Unroll&lt;/a&gt;”:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Perceba que inserimos marcações no nome do método usando o sinal “#” mais o nome das variáveis utilizadas no teste. Executando o teste novamente teremos a seguinte saída:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Identificar rapidamente onde ocorreu a falha aumenta a nossa produtividade, principalmente numa suíte de teste muito grande.&lt;/p&gt;

&lt;h1&gt;
  
  
  Testando a interação entre objetos
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Mocking&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Nem só de verificação de estado vivem nossos testes; há cenários onde é necessário explorar o comportamento do objeto sob teste do ponto de vista das interações que ele faz com outros objetos.&lt;/p&gt;

&lt;p&gt;Nesse tipo de teste (também conhecido como “&lt;em&gt;Interaction Tests&lt;/em&gt;” ou “&lt;em&gt;Collaboration Test&lt;/em&gt;”) utilizamos a técnica de “&lt;a href="http://xunitpatterns.com/Mock%2520Object.html"&gt;&lt;em&gt;Mock&lt;/em&gt;&lt;/a&gt;” (imitar) para conseguirmos analisar as interações entre os objetos sob teste.&lt;/p&gt;

&lt;p&gt;A &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_creating_mock_objects"&gt;criação de “&lt;/a&gt;&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_creating_mock_objects"&gt;&lt;em&gt;Mocks&lt;/em&gt;&lt;/a&gt;&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_creating_mock_objects"&gt;”&lt;/a&gt; é muito simples e pode ser feita de duas formas:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Ou utilizando a sintaxe Java:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Vejamos o uso do “&lt;em&gt;Mock&lt;/em&gt;” mais detalhadamente no exemplo abaixo (linhas 14, 15):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Diferente dos exemplos anteriores, nos quais verificamos o estado do objeto sob teste (ex: &lt;code&gt;user.getName() == name&lt;/code&gt;); nosso interesse agora é saber se após a fase execução (“&lt;em&gt;when&lt;/em&gt;”) o objeto “&lt;em&gt;Publisher&lt;/em&gt;” realizou as interações necessárias com os seus colaboradores “&lt;em&gt;Subscriber&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;A análise das interações é feita através de restrições, ou seja, no exemplo acima esperamos que objeto alvo “&lt;em&gt;Subscriber&lt;/em&gt;”, seja chamado através do método “&lt;em&gt;receive&lt;/em&gt;”, recebendo exatamente como argumento a palavra “&lt;em&gt;hello&lt;/em&gt;” e que isso ocorra apenas um vez.&lt;/p&gt;

&lt;p&gt;Essas restrições estão organizadas no Spock da seguinte forma:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; restrição por cardinalidade&lt;/li&gt;
&lt;li&gt; restrição de alvo&lt;/li&gt;
&lt;li&gt; restrição de método&lt;/li&gt;
&lt;li&gt; restrição de argumento&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Obs: todas as variações de restrição podem ser vistas na &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_interactions_2"&gt;documentação do Spock&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Stubbing&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Como podemos testar um objeto, de forma independente, quando ele depende do resultado retornado por outros objetos que colaboram com ele?&lt;/p&gt;

&lt;p&gt;É preciso controlar os objetos de colaboração e definir como eles devem se comportar durante as interações com o objeto sob teste.&lt;/p&gt;

&lt;p&gt;Chamamos essa técnica de “&lt;a href="http://xunitpatterns.com/Test%20Stub.html"&gt;&lt;em&gt;Stub&lt;/em&gt;&lt;/a&gt;”, onde substituímos o objeto real por um objeto que será alimentado com as entradas que desejamos utilizar no nosso testes.&lt;/p&gt;

&lt;p&gt;Alteramos o nosso exemplo de teste que agora utiliza o “&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_stubbing"&gt;&lt;em&gt;Stubbing&lt;/em&gt;&lt;/a&gt;” para definir um resultado ao método “&lt;em&gt;receive&lt;/em&gt;” da interface “&lt;em&gt;Subscriber&lt;/em&gt;” (linha 22). Dessa forma podemos validar não apenas a interação mas também o retorno esperado:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As interações com “&lt;em&gt;Stubs&lt;/em&gt;” diferem um pouco em comparação as interações como “&lt;em&gt;Mocks&lt;/em&gt;”, conforme demonstrado abaixo:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Mais uma vez, todas as variações de interações pode ser vistas na &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_returning_fixed_values"&gt;documentação do Spock&lt;/a&gt;, especialmente a parte que trata da &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_combining_mocking_and_stubbing"&gt;combinação de “&lt;/a&gt;&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_combining_mocking_and_stubbing"&gt;Mocking&lt;/a&gt;&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_combining_mocking_and_stubbing"&gt;” e “&lt;/a&gt;&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_combining_mocking_and_stubbing"&gt;Stubbing&lt;/a&gt;&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_combining_mocking_and_stubbing"&gt;”&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Trabalhando com exceções
&lt;/h1&gt;

&lt;p&gt;Por fim, porém não menos importante, precisamos ser capazes de validar quando o objeto sob teste deve lançar uma exceção.&lt;/p&gt;

&lt;p&gt;Geralmente, o uso de exceções nos testes ocorrem de duas formas:&lt;/p&gt;

&lt;p&gt;1 - Validar a ocorrência de uma exceção (“&lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_exception_conditions"&gt;&lt;em&gt;Exception Conditions&lt;/em&gt;&lt;/a&gt;”).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;2 - Simular uma exceção &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_performing_side_effects"&gt;como efeito colateral&lt;/a&gt; (utilizando “&lt;em&gt;Stubs&lt;/em&gt;”).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Ainda como pontos positivos do Spock vale listar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Spock disponibiliza um “&lt;a href="http://meetspock.appspot.com/"&gt;Web Console&lt;/a&gt;” onde podemos experimentar o seu funcionamento.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/spockframework/spock-example"&gt;Projeto de exemplo&lt;/a&gt; mostrando como configurar com: Ant, Gradle e Maven.&lt;/li&gt;
&lt;li&gt;  Ótima documentação, embasada em conceitos do &lt;a href="https://en.wikipedia.org/wiki/Agile_software_development"&gt;Agile&lt;/a&gt; e &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development"&gt;BDD&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  O framework de “Mock” do Spock é integrado, ou seja, não é preciso importar outras bibliotecas (embora também seja possível utilizá-las em conjunto com o Spock).&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://spockframework.org/spock/docs/1.3/all_in_one.html#_spring_module"&gt;Integração com o Spring&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nem tudo são flores. Importante ressaltar que, em comparação, o &lt;a href="https://junit.org/junit5/"&gt;JUnit 5&lt;/a&gt; ganha nos seguintes pontos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  100% implementado em Java.&lt;/li&gt;
&lt;li&gt;  Melhor compatibilidade com as últimas versões da JDK.&lt;/li&gt;
&lt;li&gt;  Melhor integração com as IDEs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enfim, desde que utilizei o Spock pela primeira vez não larguei mais; não apenas pelo ganho de produtividade, mas também pela forma como os testes passam a funcionar (de fato) como a documentação da aplicação.&lt;/p&gt;

&lt;p&gt;Referências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Why I prefer Spock over JUnit by Bouke Nijhuis (&lt;a href="https://www.youtube.com/watch?v=aydVJbF7Mas"&gt;YouTube&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;  Spock vs JUnit 5 - Clash of the Titans by Marcin Zajaczkowski (&lt;a href="https://www.youtube.com/watch?v=AwX3i1yWDkc"&gt;YouTube&lt;/a&gt;, &lt;a href="https://speakerdeck.com/szpak/spock-vs-junit-5-clash-of-the-titans"&gt;Slides&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;  XUnit Test Patterns - Refactoring Test Code by Gerard Meszaros (&lt;a href="http://xunitpatterns.com/"&gt;Site&lt;/a&gt;, &lt;a href="https://www.amazon.com/gp/product/B004X1D36K"&gt;Book&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>groovy</category>
      <category>test</category>
      <category>spockframework</category>
    </item>
  </channel>
</rss>
