Introdução
Neste tutorial, você aprenderá como aplicar práticas de desenvolvimento ágil utilizando o framework Red, focando na implementação de testes automatizados para garantir a qualidade e a eficiência do seu software. O desenvolvimento ágil permite que as equipes de desenvolvimento estejam mais adaptativas às mudanças de requisitos e entregas mais rápidas. Neste artigo, abordaremos desde a configuração do ambiente até a criação, teste e validação de um projeto completo em Java com Spring Boot, aplicando conceitos de testes automatizados para garantir que as funcionalidades implementadas atendam às expectativas e requisitos do negócio. Com os exemplos práticos, você se sentirá mais confiante em adotar esse modelo de desenvolvimento. Vamos começar!
Etapas
Configuração do Ambiente de Desenvolvimento
Antes de começar, verifique se você possui o JDK (Java Development Kit) e o Maven instalados em sua máquina. Você pode fazer isso executando os comandos a seguir no terminal:
commands# Verificar versões instaladas
java -version
mvn -versionCriação do Projeto Spring Boot
Utilize o Spring Initializr para gerar um novo projeto Spring Boot com as dependências necessárias. Configure o projeto com as seguintes opções: **Project**: Maven, **Language**: Java, **Spring Boot**: última versão estável, **Packaging**: Jar, **Java**: 11 ou superior. Adicione as dependências ‘Spring Web’, ‘Spring Data JPA’, e ‘H2 Database’. Baixe e descompacte o projeto em seu ambiente de trabalho.
pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>api-qualidade-software</artifactId> <version>0.0.1-SNAPSHOT</version> <name>api-qualidade-software</name> <description>API para teste de qualidade de software</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Configuração do Banco de Dados H2
Edite o arquivo `application.properties` para definir as propriedades do banco de dados H2 e habilitar o console web para visualização dos dados.
application.propertiesspring.h2.console.enabled=true spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.hibernate.ddl-auto=update
Criação da Entidade `Usuario`
Implemente a classe modelo `Usuario` que representará os usuários na aplicação. Use anotações JPA para mapear a classe à tabela do banco de dados.
Usuario.javapackage com.example.apiqualidadesoftware.model; import javax.persistence.*; @Entity @Table(name = "usuarios") public class Usuario { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String nome; @Column(nullable = false, unique = true) private String email; // Getters e Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Criação do Repositório `UsuarioRepository`
Implemente a interface `UsuarioRepository`, que estende `JpaRepository` e fornece métodos CRUD.
UsuarioRepository.javapackage com.example.apiqualidadesoftware.repository; import com.example.apiqualidadesoftware.model.Usuario; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UsuarioRepository extends JpaRepository<Usuario, Long> { // Métodos personalizados podem ser definidos aqui, se necessário }
Implementação do Serviço `UsuarioService`
Crie a classe `UsuarioService`, que contém a lógica de negócios e utiliza o `UsuarioRepository` para interagir com o banco de dados.
UsuarioService.javapackage com.example.apiqualidadesoftware.service; import com.example.apiqualidadesoftware.model.Usuario; import com.example.apiqualidadesoftware.repository.UsuarioRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class UsuarioService { @Autowired private UsuarioRepository usuarioRepository; public List<Usuario> findAll() { return usuarioRepository.findAll(); } public Optional<Usuario> findById(Long id) { return usuarioRepository.findById(id); } public Usuario save(Usuario usuario) { return usuarioRepository.save(usuario); } public Usuario update(Long id, Usuario usuarioDetails) { Usuario usuario = usuarioRepository.findById(id).orElseThrow(() -> new RuntimeException("Usuário não encontrado")); usuario.setNome(usuarioDetails.getNome()); usuario.setEmail(usuarioDetails.getEmail()); return usuarioRepository.save(usuario); } public void deleteById(Long id) { usuarioRepository.deleteById(id); } }
Implementação do Controlador `UsuarioController`
Crie a classe `UsuarioController` para expor os endpoints da API, permitindo operações CRUD.
UsuarioController.javapackage com.example.apiqualidadesoftware.controller; import com.example.apiqualidadesoftware.model.Usuario; import com.example.apiqualidadesoftware.service.UsuarioService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/usuarios") public class UsuarioController { @Autowired private UsuarioService usuarioService; @GetMapping public List<Usuario> getAllUsuarios() { return usuarioService.findAll(); } @GetMapping("/{id}") public ResponseEntity<Usuario> getUsuarioById(@PathVariable Long id) { return usuarioService.findById(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @PostMapping public Usuario createUsuario(@RequestBody Usuario usuario) { return usuarioService.save(usuario); } @PutMapping("/{id}") public ResponseEntity<Usuario> updateUsuario(@PathVariable Long id, @RequestBody Usuario usuarioDetails) { return ResponseEntity.ok(usuarioService.update(id, usuarioDetails)); } @DeleteMapping("/{id}") public ResponseEntity<Void> deleteUsuario(@PathVariable Long id) { usuarioService.deleteById(id); return ResponseEntity.noContent().build(); } }
Implementação de Testes Unitários
Crie a classe de testes `UsuarioServiceTest` para validar a lógica de negócios e operações CRUD da aplicação.
UsuarioServiceTest.javapackage com.example.apiqualidadesoftware.service; import com.example.apiqualidadesoftware.model.Usuario; import com.example.apiqualidadesoftware.repository.UsuarioRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; public class UsuarioServiceTest { @InjectMocks private UsuarioService usuarioService; @Mock private UsuarioRepository usuarioRepository; @BeforeEach public void init() { MockitoAnnotations.openMocks(this); } @Test public void testFindAll() { Usuario usuario1 = new Usuario(); usuario1.setId(1L); usuario1.setNome("Usuário 1"); usuario1.setEmail("usuario1@example.com"); Usuario usuario2 = new Usuario(); usuario2.setId(2L); usuario2.setNome("Usuário 2"); usuario2.setEmail("usuario2@example.com"); when(usuarioRepository.findAll()).thenReturn(Arrays.asList(usuario1, usuario2)); List<Usuario> usuarios = usuarioService.findAll(); assertEquals(2, usuarios.size()); verify(usuarioRepository, times(1)).findAll(); } // Testes adicionais para os métodos findById, save, update e deleteById }
Executando a Aplicação e Testes
Use o Maven para compilar e executar a aplicação. Em seguida, utilize ferramentas como Postman ou cURL para testar os endpoints da API.
commands# Compilar e executar a aplicação
mvn spring-boot:run
# Executar os testes unitários
mvn testcurl_examples# Listar todos os usuários
curl -X GET http://localhost:8080/api/usuarios
# Criar um novo usuário
curl -X POST -H "Content-Type: application/json" -d '{"nome":"Novo Usuário", "email":"novo.usuário@example.com"}' http://localhost:8080/api/usuarios
Conclusão
Neste tutorial, você aprendeu a criar uma API RESTful com Spring Boot, cobrindo desde a configuração inicial do ambiente até a implementação da lógica de negócios, expostos via um controlador. Além disso, exploramos a importância dos testes automatizados para garantir a qualidade do software. Com essas práticas, você pode agora construir aplicações mais robustas e confiáveis, além de estar mais preparado para lidar com ambientes de desenvolvimento ágil. Continue explorando as funcionalidades do Spring Boot e buscando melhorar suas habilidades em desenvolvimento de software!