GWTDO: entendendo o Specification Matching

Yan Justino
Yan Justino

--

💬 Para além dos benefícios, o uso de especificações em BDD impõe  alguns desafios: o rasteio de falhas, a duplicação de elementos da especificação e a necessidade de mante-la em adição aos testes de unidade. Apresentaremos nesse artigo o recurso do Specification Matching da biblioteca GWTDO e como ele pode auxiliar na escrita de especificações e garantir sua integridade em relação ao mapeamento.

Para lidar com os desafios de manter especificações em BDD, a biblioteca GWTDO oferece uma solução simples: o Specification Matching. Esse recurso permite criar uma correspondência entre a especificação, o mapeamento e o código do teste. Utilizaremos os exemplos de código a seguir para descrever esse recurso:

Figura 1. Especificação BDD (xUnit)

O código ilustrado na Figura 1 representa um teste no qual é descrito um cenário chamadoUser trades stocks seguido por uma chamada ao método setup_user_trades_stocks_scenario do componente Mapper.

Figura 2. Método de mapeamento do cenário

A Figura 2 ilustra o mapeamento da espcificação contida na Figura 1. É perceptível que tanto a especificação do teste quanto a especificação do mapeamento possuem a mesma estrutura, exceto pela chamada do métodoMapAction(...) no final de algumas expressões. Falaremos desse método mais adiante.

Specification Matching

O Specifiation Matching é um conjunto de recursos da DSL GWTDO composto por duas funcionalidades: a) a correspondência entre especificação e mapeamento; b) e a correnspondência entre o mapeamento e a função.

A) a correspondência entre especificações e mapeamento:
É a função responsável por manter a integridade entre a especificação e o mapeamento.

Vamos supor que o desenvolvedor bob 👨 altere o código da Figura 1, modificando a expressão I have 100 shares of MSFT stock para I have 99 shares of MSFT stock . A execução desse teste resulta em uma falha, como ilustra a Figura 3.

Figura 3. Falha na execução do teste ao modificar a especificação

Nesse resultado a expressão I have 99 shares of MSFT stock é destacada com o valor (NOT MAPPED) , indicando que ela não foi mapeada.

Agora, imaginemos que a desenvolvedora alice 👩 adiciona um pouco mais de complexidade no seu teste ao incluir a expressão I have 150 shares of APPL stockna especifiação, sem mapea-la. Ao executar o teste, teremos o seguinte resultado:

Figura 4. Falha na execuçãod o teste ao adicionar expressões não mapeadas

Como ilustra a Figura 4, uma falha ocorreu dada a ausência do mapeamento da expressão I have 150 shares of APPL stock .

❗️️ A correspondência entre especificação e mapeamento sempre ira ocorrer na seguinte direção: espcificação -> mapeamento.Caso haja mais expressões no mapeamente do que na especificação, elas serão ignoradas durante a execução do teste!

B) a correspondência entre expressão do mapeamento e uma função:
É a funçao da classe de mapemanto que perminte a integração entre a expressão e o código do teste, através da chamada ao método MapAction(). Esse método é responsável por satisfazer a Correctness formulae[3]

{ X ⇒ Y | Y = f:P A Q }

Essa formula expressa que um “significante” X (expressão) implica em um “significado” Y (ação), tal que Y, representa uma função A (Action<T>) que altera o estado de um domíno P (estado da fixture antes da ação) para um estado Q (estado a fixture após ação).

Figura 5. Mapeamento de uma expressão

Como ilustra a Figura 5, essa operação é implementada pelo GWTDO da seguinte forma: a expressão I have 100 shares of MSFT stock é mapeada para uma função do tipoAction<StockFixture> , encapsulada pelo atributo Have100SharesOfMsfStock , e que executa o método Buy("MSFT, 100) , alterando o estado do objeto Stock dentro da Fixture f. Essa abordagem possibilita que expressões em cenários diferentes reutilizem uma mesma função, diminuindo a complexidade e a repetição de código.

❗️️ Durante o processo de especificação, as ações do mapeamento podem não estar completamente prontas ou compreendidas. Para isso, o GWTD oferece a propriedade DefaultAction. Ela pode ser utilizada como ação temporária enquanto a ação final não está disponível. O trecho de código abaixo exemplifica seu o uso desse recurso.GIVEN | "I have 100 shares of MSFT stock".MapAction(DefaultAction) 

Conclusão

Apresentamos nesse artigo o recurso do Specification Matching da biblioteca GWTDO. Vimos o quanto ele pode auxiliar a escrita de especificações e garantir sua integridade em relação ao mapeamento.

Esperamos que tenha gostado do artigo! Deixe seu comentário e, se for de seu interesse, participe do projeto GWTDO. Para isso, basta acessar o repositório no github através do endereço https://github.com/8T4/gwtdo.

Até a próxima,

⚠️ ATENÇÃO! Esta é uma versão prévia do artigo, que encontra-se em revisão! É possível que sejam encontrados alguns erros ortográficos e de referências.

Referências

  1. L. P. Binamungu, S. M. Embury and N. Konstantinou, “Maintaining behavior driven development specifications: Challenges and opportunities,” 2018 IEEE 25th International Conference on Software Analysis, Evolution and Reengineering (SANER), Campobasso, Italy, 2018, pp. 175–184, doi: 10.1109/SANER.2018.8330207.
  2. Fowler, M., 2021. bliki: GivenWhenThen. [online] martinfowler.com. Available at: <https://martinfowler.com/bliki/GivenWhenThen.html> [Accessed 19 April 2021].
  3. Meyer, B. (1997). Object-oriented software construction (Vol. 2, pp. 331–410). Englewood Cliffs: Prentice hall.

--

--

Yan Justino
Yan Justino

MSc. Software Engineering — MCP | MCSA | MCSD | OCA