QUALIDADE DE
CÓDIGO
Test Driven Development
 Por que é importante?
 Código de produção testável
 Refatoração sem medo
 Código melhor estruturado
 O que não testar?
 Cadastros
 Leitura/Gravação de arquivos
 Independência
 Banco de dados
 Arquivos do sistema
 Arquivos de configuração
Mocks
 Então como testar?
 Mocks
 Exemplo DataAccess
 Testar a conversão dos Feriados do SIAP em DateTime
 Biblioteca Moq.
 Testes Unitários
 Deve testar um único método. Todas as outras
dependências que esse método usa devem ser mockadas.
 Evitar métodos estáticos
 Não é possível mocká-los
 DateTime.Now
 Exemplo Business & DateTime.Now
 Mostrar código do SIGEP (ApontamentoServicoDeve)
Exemplo: classe não testável
 Classe não testável:
Refatoração
 O código de produção
deve ser escrito o mais
simples possível para
passar
 Depois de escrever
vários testes e códigos
de produção, pode-se
perceber que há códigos
duplicados ou que
poderiam ser melhores
escritos
 Então chegou a hora de
refatorá-los
Refatorando ConsultaArquivo
 Temos que testar a regra de obter o texto SQL
sem depender de um arquivo do
sistema, como?
 Dependency Inversion
1º
• Vamos fazer a classe ConsultaArquivo não depender mais
dos métodos estáticos da classe File
2º
• ConsultaArquivo exigirá no construtor uma interface
IFileHelper
3º
• IFileHelper conterá 2 métodos: Existe(...) e LeTodoTexto(...)
4º
• Mockamos o IFileHelper para testar o método
ObterConsultaPorNome(...)
ConsultaArquivo Refatorada
Testes de Integração
 Poderíamos testar o FileHelper, mas seria um teste
de Integração e não um teste de unidade.
 Seria um teste de Integração com o sistema de
arquivos do windows
 Testes de Integração se caracterizam por
necessitarem de um ambiente preparado para o
teste funcionar
 Acesso a arquivos
 Acesso ao banco de dados
 Acesso a WebServices
 Testar unidades em conjunto (integradas)
Nomenclatura
 Nome classe de teste:
 NomeClasseTestadaDeve
 NomeClasseTestadaNomeMetodoDeve
 Nome dos métodos do teste:
 Deve ser uma ação que a classe testada deve fazer
 Exemplos:
 PedidoBusinessDeve
 Quebrar_Pedidos_Por_Representante_Quando_Parametro_Estiver_
Setado
 Retornar_Apenas_Pedidos_Faturados_Da_Conta_X
 Totalizar_Itens_Pedidos_Corretamente
 Lancar_Excecao_Quando_Pedido_Estiver_Bloqueado
 Por quê?
 Facilita o entendimento sobre o que está sendo testado
 Facilita para o desenvolvedor escrever o teste
Nomenclatura - AAA
 Arrange
 Organiza os objetos antes de executar o teste
 Act
 Executa o método que está testando
 Assert
 Verifica as condições para que o teste passe
 Por quê?
 Testes mais organizados
 Testes mais limpos
 Bater o olho e saber o que e como certa
funcionalidade está sendo testada
SUGESTÕES DE
MELHORIA
Opiniões e Debates
Muitas dependências
 Classe recebe vários parametros no construtor
 Talvez essa classe deva ser quebrada em mais
classes
 Agrupar os parametros em outra classe e fazer o
construtor receber essa nova classe.
Business
 Acho que não devíamos ficar presos as
Business.
 Regra de negócio deve ser na Business, ok.
 Mas também poderíamos criar outras classes
que a Business usa.
 Exemplo: validação do Pedido é complexa
 Talvez criar uma classe ValidadorPedido(Pedido)
 Passar tudo o que é preciso para validar o Pedido
 Na Business de Pedido chamar essa classe.
 Atualmente os métodos das Business possuem
muito código e as regras estão obscuras
Business
 Acho que poderíamos ter mais Business ao
invés de apenas Business relativas ao Model.
 Exemplo CRM:
CampanhaBusinessComplement
 Possui método CriarAgendamentos
 Poderia ser criado uma Business relativa a
Agendamentos, pois a criação de Agendamentos
é complexa e poderia ser isolada.
Parametros out
 ReadComplete
 Por que não retornar apenas uma classe e nessa
classe colocar todos os parametros out?
 CreateComplete
 Por que não receber essa mesma classe que foi
criada no item anterior ao inves de vários
parametros out?
 Acho que não devíamos ficar presos aos
Models.
 Mais classes poderiam ser criadas para que as
responsabilidades sejam divididas.
Factories
 São classes que funcionam como uma fábrica
de objetos.
 Às vezes para instanciar uma classe, é
requerido vários parametros ou algumas
regras especificas.
 Essas regras poderiam estar encapsuladas em
uma Factory
 Exemplo CRM:
AtividadeFactory
 Poderia ser criado uma classe Factory que
recebesse os objetos destacados e retornasse
uma instancia de AtividadeInfo.
Dependência de Web Services
 Acho que não devíamos usar o Schema gerado
pelo wsdl
 Se o schema mudar, toda a aplicação terá que ser
alterada
 Solução
 Criar nossas próprias classes
 Criar camada intermediária entre nossas classes e o
schema
 Converter nossas classes para o schema
 Converter o schema para nossa classe
 Se schema mudar, precisamos mexer apenas nessa
camada de conversão
 Exemplo ruim: DualNFe usa os schemas
 Exemplo bom: PortalTiss usa classes próprias
Referências
 Software Practices, Pluralsight
 Principles of Object Oriented Design
 Design Patterns
 Clean Code A Handbook of Agile Software
Craftsmanship, Robert C. Martin
 DDD Quickly, Abel Avram & Floyd Marinescu
 Resumo de DDD por Eric Evans

Qualidade de Código

  • 1.
  • 2.
    Test Driven Development Por que é importante?  Código de produção testável  Refatoração sem medo  Código melhor estruturado  O que não testar?  Cadastros  Leitura/Gravação de arquivos  Independência  Banco de dados  Arquivos do sistema  Arquivos de configuração
  • 3.
    Mocks  Então comotestar?  Mocks  Exemplo DataAccess  Testar a conversão dos Feriados do SIAP em DateTime  Biblioteca Moq.  Testes Unitários  Deve testar um único método. Todas as outras dependências que esse método usa devem ser mockadas.  Evitar métodos estáticos  Não é possível mocká-los  DateTime.Now  Exemplo Business & DateTime.Now  Mostrar código do SIGEP (ApontamentoServicoDeve)
  • 4.
    Exemplo: classe nãotestável  Classe não testável:
  • 5.
    Refatoração  O códigode produção deve ser escrito o mais simples possível para passar  Depois de escrever vários testes e códigos de produção, pode-se perceber que há códigos duplicados ou que poderiam ser melhores escritos  Então chegou a hora de refatorá-los
  • 6.
    Refatorando ConsultaArquivo  Temosque testar a regra de obter o texto SQL sem depender de um arquivo do sistema, como?  Dependency Inversion 1º • Vamos fazer a classe ConsultaArquivo não depender mais dos métodos estáticos da classe File 2º • ConsultaArquivo exigirá no construtor uma interface IFileHelper 3º • IFileHelper conterá 2 métodos: Existe(...) e LeTodoTexto(...) 4º • Mockamos o IFileHelper para testar o método ObterConsultaPorNome(...)
  • 7.
  • 8.
    Testes de Integração Poderíamos testar o FileHelper, mas seria um teste de Integração e não um teste de unidade.  Seria um teste de Integração com o sistema de arquivos do windows  Testes de Integração se caracterizam por necessitarem de um ambiente preparado para o teste funcionar  Acesso a arquivos  Acesso ao banco de dados  Acesso a WebServices  Testar unidades em conjunto (integradas)
  • 9.
    Nomenclatura  Nome classede teste:  NomeClasseTestadaDeve  NomeClasseTestadaNomeMetodoDeve  Nome dos métodos do teste:  Deve ser uma ação que a classe testada deve fazer  Exemplos:  PedidoBusinessDeve  Quebrar_Pedidos_Por_Representante_Quando_Parametro_Estiver_ Setado  Retornar_Apenas_Pedidos_Faturados_Da_Conta_X  Totalizar_Itens_Pedidos_Corretamente  Lancar_Excecao_Quando_Pedido_Estiver_Bloqueado  Por quê?  Facilita o entendimento sobre o que está sendo testado  Facilita para o desenvolvedor escrever o teste
  • 10.
    Nomenclatura - AAA Arrange  Organiza os objetos antes de executar o teste  Act  Executa o método que está testando  Assert  Verifica as condições para que o teste passe  Por quê?  Testes mais organizados  Testes mais limpos  Bater o olho e saber o que e como certa funcionalidade está sendo testada
  • 11.
  • 12.
    Muitas dependências  Classerecebe vários parametros no construtor  Talvez essa classe deva ser quebrada em mais classes  Agrupar os parametros em outra classe e fazer o construtor receber essa nova classe.
  • 13.
    Business  Acho quenão devíamos ficar presos as Business.  Regra de negócio deve ser na Business, ok.  Mas também poderíamos criar outras classes que a Business usa.  Exemplo: validação do Pedido é complexa  Talvez criar uma classe ValidadorPedido(Pedido)  Passar tudo o que é preciso para validar o Pedido  Na Business de Pedido chamar essa classe.  Atualmente os métodos das Business possuem muito código e as regras estão obscuras
  • 14.
    Business  Acho quepoderíamos ter mais Business ao invés de apenas Business relativas ao Model.  Exemplo CRM: CampanhaBusinessComplement  Possui método CriarAgendamentos  Poderia ser criado uma Business relativa a Agendamentos, pois a criação de Agendamentos é complexa e poderia ser isolada.
  • 15.
    Parametros out  ReadComplete Por que não retornar apenas uma classe e nessa classe colocar todos os parametros out?  CreateComplete  Por que não receber essa mesma classe que foi criada no item anterior ao inves de vários parametros out?  Acho que não devíamos ficar presos aos Models.  Mais classes poderiam ser criadas para que as responsabilidades sejam divididas.
  • 16.
    Factories  São classesque funcionam como uma fábrica de objetos.  Às vezes para instanciar uma classe, é requerido vários parametros ou algumas regras especificas.  Essas regras poderiam estar encapsuladas em uma Factory  Exemplo CRM:
  • 17.
    AtividadeFactory  Poderia sercriado uma classe Factory que recebesse os objetos destacados e retornasse uma instancia de AtividadeInfo.
  • 18.
    Dependência de WebServices  Acho que não devíamos usar o Schema gerado pelo wsdl  Se o schema mudar, toda a aplicação terá que ser alterada  Solução  Criar nossas próprias classes  Criar camada intermediária entre nossas classes e o schema  Converter nossas classes para o schema  Converter o schema para nossa classe  Se schema mudar, precisamos mexer apenas nessa camada de conversão  Exemplo ruim: DualNFe usa os schemas  Exemplo bom: PortalTiss usa classes próprias
  • 19.
    Referências  Software Practices,Pluralsight  Principles of Object Oriented Design  Design Patterns  Clean Code A Handbook of Agile Software Craftsmanship, Robert C. Martin  DDD Quickly, Abel Avram & Floyd Marinescu  Resumo de DDD por Eric Evans