Home | Escopo | Processo | Design/Mockups | Gerência | Estudos | Arquitetura | Contratos | BD | Qualidade | Configuração | Instalação | Instruções | Utilização | Analytics | Infraestrutura | Dicas |
---|
Qualidade de Software
Descrição
Nesta seção, detalhamos as metodologias e procedimentos adotados para garantir a qualidade do software, juntamente com o uso de design patterns e ferramentas para manter a consistência e a confiabilidade do código. Nossa abordagem visa não apenas evitar erros, mas também assegurar que o código seja escalável, manutenível e aderente aos princípios de boas práticas de desenvolvimento.
Sumário
- Estrutura do backend
- Índices de Qualidade
- Testes
- Padronização de Código
- Fluxo Gitlab
- Commit
- Merge
- UX/UI
- Documentação
- Persistência de Dados
Índices de Qualidade
- Jest: Ferramenta de testes unitários.
- Eslint: Ferramenta para análise sintática.
- Prettier: Ferramenta para formatação de código e padronização de estilo.
Utilizamos essas ferramentas para manter a qualidade do código e garantir que ele atenda às especificações de funcionalidade e estilo. O Jest valida o comportamento correto dos módulos individuais através de testes unitários. O Eslint ajuda a detectar erros de sintaxe e práticas de código incorretas, enquanto o Prettier formata automaticamente o código para manter a consistência e legibilidade.
Benefícios
- Jest: Reduz a probabilidade de introdução de bugs ao garantir que as funções se comportam conforme o esperado.
- Eslint: Aumenta a qualidade geral do código, detectando padrões que podem levar a erros ou diminuir a legibilidade.
- Prettier: Garante que o código siga um padrão visual consistente, tornando-o mais fácil de ler e manter.
Testes
- Jest: Testes unitários.
- Insomnia/Postman: Testes de integração.
Implementamos dois níveis de testes:
- Testes Unitários: Validam a funcionalidade isolada de cada componente, sendo desenvolvidos pelo autor da funcionalidade.
- Testes de Integração: Simulam o uso do sistema como um todo, testando a integração dos componentes. São realizados por um colega desenvolvedor utilizando ferramentas como Insomnia ou Postman para testar a API.
Benefícios
- A combinação de testes unitários e de integração permite detectar erros tanto no nível de implementação quanto no nível de interação entre diferentes módulos, garantindo uma maior robustez e confiabilidade do sistema.
Padronização de Código
- Prettier: Automatiza a formatação de código para garantir consistência em toda a base de código.
- Husky: Configurado para executar hooks Git que validam o código antes do commit.
Nosso fluxo de padronização de código segue dois momentos principais:
- Pré-commit (localmente): Husky, em conjunto com Eslint e Prettier, valida e formata o código antes que ele seja enviado para o repositório.
- No GitLab (após o push): O código é novamente validado no CI/CD para garantir que esteja de acordo com os padrões estabelecidos.
Benefícios
- Automatizar a padronização e verificação de código minimiza o retrabalho, elimina inconsistências e garante que o código enviado para produção esteja sempre em conformidade com as regras definidas.
Fluxo Gitlab
- Husky: Executa verificações automáticas de qualidade no ciclo de commits.
- Lint-Staged: Verifica apenas os arquivos modificados, otimizando o processo de validação.
- Conventional Commits: Padroniza mensagens de commit para facilitar o rastreamento de alterações.
GitFlow
Utilizamos o GitFlow para organizar o desenvolvimento, onde cada nova tarefa ou funcionalidade é desenvolvida em uma branch separada e, ao finalizar, enviada para a branch develop
através de um Merge Request (MR).
Procedimento para criação de Branches
O padrão a ser seguido para a nomeação de branches é o seguinte:
- usar um prefixo (fortemente recomendado)
- usar identificador (opcional)
- usar user storie, quando houver (recomendado)
- usar número da issue (opcional)
- descritivo do objetivo principal (fortemente recomendado)
Formato esperado:
prefix/ticket-number-short-subject
prefix/id-short-subject
prefix/us-short-subject
Exemplos:
feature/US01_T10-endpoint-cadastro-produto
bugfix/US01_T10-endpoint-cadastro-produto
hotfix/13-endpoint-cadastro-produto
release/US01_T10-endpoint-cadastro-produto
docs/A2023-endpoint-cadastro-produto
Prefixos Comuns
Os prefixos são usados para identificar rapidamente o propósito de uma branch. Estes são os prefixos mais comuns:
- feature/: Usado para o desenvolvimento de novas funcionalidades.
- bugfix/: Usado para corrigir bugs não críticos.
- hotfix/: Usado para correções urgentes de bugs críticos diretamente na produção.
- release/: Usado para preparar uma nova versão para lançamento.
- docs/: Usado para modificar ou adicionar documentação.
Convenções
-
Uso de Hífen e Barra: Utilize barras
/
para separar categorias e hífens-
para separar palavras, garantindo que o nome da branch seja legível.
Exemplo:feature/nova-funcionalidade
. -
Letras Minúsculas: Mantenha o nome das branches em letras minúsculas, usando apenas caracteres alfanuméricos e hífens.
-
Ticket de Rastreamento: Se houver um número de ticket relacionado a uma tarefa, ou for usar um id ou a User Storie, inclua esse dado no início do nome da branch.
Exemplo:feature/US01_T10-adicionar-login
. -
Evitar Nomes Longos: Nomes muito longos podem dificultar a navegação e a diferenciação entre branches. Mantenha-os curtos e descritivos.
Exemplo:feature/autenticacao-2fa
em vez defeature/adicionar-sistema-de-autenticacao-com-dois-fatores
.
Na prática:
-
Crie uma nova branch a partir da
develop
com o formato "US00T00-TaskName", por exemplo:US24T03-CreateStudent
-
Use mensagens de commit descritivas e no imperativo. Exemplo:
feat: added registration form
Evite mensagens genéricas como:
Corrige service
Um exemplo mais claro seria:
fix: corrects error message in getAll method of userService
-
Após concluir o desenvolvimento, crie um MR para a branch
develop
. O merge só será permitido se todos os testes e verificações de sintaxe forem bem-sucedidos.
Benefícios
- Esse fluxo mantém o histórico de desenvolvimento limpo e organizado, facilitando o rastreamento de mudanças e a resolução de conflitos, além de garantir que apenas código testado e validado seja integrado à base de código principal.
Commit
Mensagens de commit são essenciais para documentar o que foi alterado e por quê. Seguir um padrão garante que essas mensagens sejam informativas e fáceis de entender.
Conventional Commits
Adotamos o padrão Conventional Commits para nomear as mensagens de commit. Esse padrão descreve as mudanças de forma clara e padronizada, facilitando o entendimento e o rastreamento do histórico de mudanças.
Mensagem de Commit:
<tipo>: <descrição curta>
[Corpo opcional]
[Rodapé opcional]
Tipos Comuns de Commits
- feat: Quando se adiciona uma nova funcionalidade ao projeto.
- fix: Para correção de bugs.
- docs: Alterações na documentação.
- style: Alterações que não afetam o significado do código (formatação, por exemplo).
- refactor: Mudanças que não corrigem bugs nem adicionam funcionalidades, mas melhoram a estrutura do código.
- test: Adição ou modificação de testes.
Boas Práticas para Commit
-
Modo Imperativo: Escreva a mensagem do commit no modo imperativo (exemplo: "adicionar", "corrigir") como se fosse uma instrução.
Exemplo:fix: corrigir erro de autenticação
. -
Descrição Curta e Objetiva: A linha principal da mensagem de commit deve ser breve (máximo 50 caracteres) e descritiva, sem ponto final.
Exemplo:feat: adicionar suporte a múltiplos usuários
. -
Rodapé (opcional): Use o rodapé para fornecer informações adicionais, como referências a tickets, ou avisos sobre mudanças críticas (ex:
BREAKING CHANGE
).
Exemplo de Mensagem Completa de Commit
feat: adicionar autenticação com OAuth
Esta mudança adiciona o suporte a autenticação com OAuth para
permitir login com redes sociais.
BREAKING CHANGE: O endpoint de login foi modificado para suportar
novos métodos de autenticação.
Benefícios
- Com commits padronizados, o histórico de mudanças fica mais legível e estruturado, o que auxilia no gerenciamento de versões, automatizações e na compreensão do que foi alterado.
Merge
- GitFlow e Conventional Commits: Para realizar o merge, o código deve passar pelos testes unitários e de integração, bem como pela validação de sintaxe.
Apenas usuários com a permissão de "maintainer" podem realizar merges nas branches develop
e main
.
Observação: Consulte a seção Merge Request no menu Processo para mais detalhes sobre o processo.
Benefícios
- Este processo rigoroso de merges garante que o código enviado para as branches principais já tenha sido amplamente validado, evitando problemas em produção.
Merge Request (MR)
- Crie uma nova MR a partir da sua branch com o formato "US00T00-TaskName", por exemplo:
US24T03-CreateStudent
UX/UI
Para garantir uma experiência de usuário satisfatória, seguimos práticas de design que buscam a simplicidade, usabilidade e acessibilidade. O objetivo é garantir que as interfaces sejam intuitivas e eficientes, proporcionando uma experiência agradável ao usuário.
Documentação
Swagger API
Utilizamos Swagger para documentar nossa API, fornecendo uma interface clara e interativa para visualizar e testar os endpoints disponíveis. Isso facilita a comunicação entre desenvolvedores e stakeholders, e melhora a eficiência no desenvolvimento de integrações.
Benefícios
- A documentação com Swagger permite que tanto desenvolvedores quanto outros membros da equipe visualizem e interajam com a API de forma clara e eficiente.
Persistência de Dados
PostgreSQL
Utilizamos PostgreSQL como banco de dados relacional para garantir integridade e eficiência na manipulação de dados.
Padrões de Schema
- Utilize
snake_case
para nomear colunas e tabelas. - Inclua sempre campos
created_at
eupdated_at
. - Adote o uso de campos booleanos como
active
para controle de status. - Utilize
json
para campos com dados dinâmicos. - Prefira
uuid
ao invés deid
tradicional, o que facilita a replicação e a clusterização.
Para campos categóricos, utilize strings ou enums em vez de valores numéricos. Exemplo:
-
usertype: "Admin"
ao invés deusertype: 0
-
gender: "Female"
ao invés degender: 'F'
Benefícios
- Utilizar
uuid
melhora a escalabilidade e flexibilidade do sistema, especialmente em ambientes distribuídos. O uso dejson
facilita a armazenagem de dados semiestruturados, enquanto a padronização dos tipos de dados melhora a clareza do schema.