ArchUnit - Teste a sua Arquitetura Java

Autor: Jonathan Neves

É indiscutível a importância dos testes unitários/automatizados em projetos e como ele pode prevenir possíveis erros futuros e manter a qualidade de código, garantindo que sua aplicação continue funcionando após alguma alteração em seu código. Além dos testes que estamos familiarizados, é possível também criar testes para Arquitetura do Projeto utilizando a ferramenta ArchUnit

Seguindo esses princípios, conseguimos manter a organização da arquitetura do projeto, tornando mais legível de entender do que se trata cada classe, pasta e pacote, facilitando a entrada e adaptação de novos desenvolvedores no projeto. 

ArchUnit é uma biblioteca gratuita e simples para testar a arquitetura do seu código Java usando qualquer framework, se o seu código respeita os padrões dos projetos, como por exemplo, um modelo MVC (model-view-controller). Ou seja, é possível verificar dependências de pacotes, classes, camadas, pastas, etc. Também existe suporte para as linguagens .NET/C#. 

Para mais informações acesse o site: https://www.archunit.org/ 

Configuração 

● Passo 1: 

Primeiramente é necessário instalar a dependência maven ou gradle dele no seu projeto, é possível encontrar a última versão da dependênia no site MVN Repository: https://mvnrepository.com/artifact/com.tngtech.archunit/archunit 

Após isso, cole a dependência abaixo em seu projeto Maven, no arquivo pom.xml: 

<dependency> 

<groupId>com.tngtech.archunit</groupId> 

<artifactId>archunit</artifactId> 

<version>0.23.1</version> 

<scope>test</scope> 

</dependency>

Se for projeto Gradle, cole no arquivo build.gradle: 

dependencies { 

testImplementation 'com.tngtech.archunit:archunit:0.23.1' } 

● Passo 2: 

Após a IDE instalar as dependências e buildar o projeto, já é possível iniciar os testes. Neste exemplo estaremos trabalhando com o projeto Spring Boot, onde utilizamos a biblioteca em nosso projeto e explicaremos melhor nossa estrutura de pastas e classes para realização de alguns testes. 

Bem, segundamente criaremos nossa classe de teste, chamada “ArchitectureTest”. Note que só é necessário uma anotação do spring “@SpringBootTest”, não será necessário mockar ou acessar base de dados. Neste primeiro exemplo iremos explicar a estrutura de código do ArchUnit que é bem simples de usar, siga o exemplo da imagem abaixo: 

No método de teste criado chamado “testArchitetureRules()”, temos os seguintes passos: 

1. JavaClasses importedClasses = new 

ClassFileImporter().importPackages("br.org.sesisc.smart.controllers"); 1

Importação das classes dentro de um package (Pasta). Na função “importPackagesinformamos o caminho que queremos extrair das classes, neste caso “br.org.sesisc.smart.controllers”. Com a variável “importedClassesconseguimos extrair informações gerais de classe, como por exemplo: nome da classe, tipo de acesso modificador (private, public e protected), anotações utilizadas, caminho, tipo de classe (Interface, Enum), pacotes javas, entre outros. 

2. ArchRule rule = classes()... 

São as regras de testes, quais são as classes filtradas e quais são as condições que serão testadas nas classes. Aqui existem inúmeras possibilidades que podem se definir com base em seu projeto. A seguir alguns exemplos básicos de “ArchRule”

Exemplo 1: Controllers 

Neste exemplo estamos realizando os testes em todas as classes dentro da pasta controllers do projeto. Primeiramente, devemos seguir com o método classes().that()” e dizer quais classes eles irão filtrar. Neste caso, “.areAnnotatedWith(RestController.class).and().haveSimpleNameNotStartingWi 

th(“Generic”)” irá filtrar apenas classes que tem anotação “@RestController” e que não comece com nome “Generic”

Em seguida continuamos a lógica com “.should()” definindo as lógicas de testes que a classe deverá respeitar. Neste caso, “beAnnotatedWith(RequestMapping.class).andShould().bePublic().andShould() .haveSimpleNameEndingWith(“Controller”);” (pode ser utilizado “orShould()” também) que irá testar se estas classes têm anotação obrigatória “@RequestMapping”, se são públicas e se terminam com “Controller”. Com isso, temos a lógica pronta para as classes Controllers. Veja abaixo o padrão da classe “Controller” que deve ser respeitada: 

Exemplo 1: UserController 

Exemplo 2: Services 

Neste exemplo iremos filtrar classes dentro do pacote “services” que tenham a anotação “@Service” e que não começam com nome “Generic”. Será testado ainda se estas classes são públicas e terminam com nome “Service” ou “ServiceImpl”. Com isso, temos a lógica pronta para as classes Services. Veja abaixo o padrão da classe Service que deverá ser respeitada: 

Exemplo 2: ParamService 

3. rule.check(importedClasses); 

Realiza o teste final em todas as classes importadas com base nas regras criadas anteriormente. A parte final, onde dirá se seu projeto está ou não respeitando os padrões propostos dentro dos testes. 

● Passo 3: 

Execute os testes na classe criada, no nosso caso “ArchitectureTest.class”. Caso seu projeto esteja respeitando os padrões estabelecidos nas regras do ArchUnit, o teste terá êxito conforme abaixo: 

Caso alguma classe fuja do padrão, como: nome incorreto, pasta incorreta, falta de anotação, entre outros, o teste falhará e informará qual classe está incorreta para correção. Como mostra o exemplo abaixo de uma classe incorreta: 

Neste exemplo, renomeie erronea e propositalmente a classe “ProfileController.java” para “ProfileControl.java”. Veja que o teste unitário rapidamente detectou o erro dizendo o seguinte: “br.org.sesisc.smart.controllers.profiles.ProfileControl does not end with 'Controller' ”, indicando que a seguinte classe não termina com nome “Controller” (ProfileControl) e portanto deverá ser corrigida. Os testes unitários ArchUnit funcionam desta forma, detectando falhas que fujam do escopo da arquitetura do projeto, seja classes e pacotes incorretos ou uma classe fora de sua respectiva pasta, entre outras possibilidades. 

Conclusão 

A biblioteca ArchUnit entrega uma série de funções para serem utilizadas para cada proposta, basta analisar qual melhor atende às suas necessidades e adequar seu código corretamente. Para mais informações de como utilizar, siga a documentação do ArchUnit: https://www.archunit.org/userguide/html/000_Index.html#_introduction 

Neste artigo usamos alguns exemplos utilizando SpringBoot, respeitando as anotações e o padrão de nome de classes usada no framework. Inclusive, já estamos começando a adoção do ArchUnit em nossos projetos para manter a qualidade da arquitetura do projeto para que os demais desenvolvedores saibam e respeitem os padrões propostos. 

Compartilhe

[shareaholic app="share_buttons" id_name="post_below_content"]

Inscreva-se