Programação Orientada a Objetos

POO com Testes Unitários

TDD com Java e JUnit

Henrique Vignando

  • Mestre em Ciências da Computação (UEM)
  • Bacharel em Informática (UEM)
  • Líder técnico e engenheiro de dados e software na Mentorstec
  • 9 anos em desenvolvimento de software
  • 2 anos com engenharia de dados
  • 1 ano com liderança técnica.
  • Palestrante no Pentaho Day 2019.
  • Entusiasta cultural das rotinas e pipelines de dados, arquitetura de software, boas práticas e padronizações

Programa

Parte "soft skills"

  • Breve história do Java
  • Características da linguagem
  • Bibliotecas da Classe Java
  • Ambiente de desenvolvimento
  • Boas Práticas
    • Clean Code, SOLID, KIS, etc...
  • Básico de UML

Programa

  • Interfaces

  • Enums

  • Generics

  • Collections

  • Exceptions

  • Serialization

Parte "hard skills" OO

  • Abstração de Dados

  • Encapsulamento

  • Herança

  • Polimorfismo

  • Composição

  • Associação

  • Classes Abstratas x Classes Concretas

Programa

Parte "hard skills" Testes

  • Técnicas TDD e BDD

  • Teste unitários e Suites de Testes

  • Testes de integração

  • JUnit

  • asserts e matchers

  • Hamcrest

  • Mockito

  • Cucumber

  • Algoritmos
  • Lógica de Programação
  • Estruturas de Dados 
  • Banco de Dados

Premissas

Desafio

Implementar uma calculadora usando

Java

História Java

  • Java é uma evolução do C++ que evoluiu do C que evoluiu do B utilizada para construir o UNIX pela Bell Laboratories.
  • C 1972 => Denis Ritchie (Bell Laboratories)
  • C++ 1980 => Bjarne Stroustrup (Bell Laboratories)
  • IBM-PC 1981 => microprocessadores da Intel para computadores pessoal
  • Oak (carvalho) 1991 => James Gosling (Sun Microsystems - projeto de pesquisa Green) 
    • Visita a cafeteria com café da cidade de Java
    • A pesquisa continuou até...

História Java

  • Boom da internet 1995 => Sun viu oportunidade na Web, nessa época nas páginas não existia muita interatividade.

  • Anuncio oficial do JAVA em Maio de 1995 => Em uma conferência

  • Em 2004 Java atingiu a marca de 3 milhões de desenvolvedores em todo mundo

  • Oracle 2008 => Oracle Corporation adquire a Sun Microsystems, por US$ 7,4 bilhões

  • É a linguagem de maior referência no mercado de desenvolvimento de software.

História Java

Características Java

  • Suporte à orientação a objetos
  • Portabilidade
  • Segurança
  • Linguagem Simples
  • Alta Performance
  • Dinamismo
  • Compilada (o compilador pode executar os bytecodes do Java diretamente em qualquer máquina);
  • Distribuído
  • Independente de plataforma
  • Fortemente tipada

Características Java

  •  Máquina Virtual Java ou JVM (Java Virtual Machine)

Bibliotecas da Classe Java

  • Programas Java consistem em partes chamadas classes. As classes incluem partes chamadas métodos que realizam tarefas e retornam informações quando as tarefas são concluídas.
  • A maioria dos programadores Java tira proveito das ricas coleções de classes existentes nas bibliotecas de classe Java, que também são conhecidas como Java APIS (Application Programming Interfaces).

Bibliotecas da Classe Java

  • Existem dois aspectos para aprender o "mundo" do Java.
    • Primeiro aspecto é a própria linguagem Java, de modo que você possa programar suas próprias classes
    • Segundo são as classes nas extensas bibliotecas de classe Java.
  • Java 8 API https://docs.oracle.com/javase/8/docs/api/.

Ambiente de Desenvolvimento

  • Programas Java passam por cinco fases no contexto do Java SE Development Kit (JDK),
    • edição
    • compilação
    • carregamento
    • verificação
    • execução

Ambiente de Desenvolvimento

  • Integrated Development Environments (IDE's) fornecem ferramentas que suportam o processo de desenvolvimento de software em Java, incluindo editores para escrever e editar programas e depuradores para localizar erros de lógica.
  • IDE's populares:
    • IntelliJ IDEA (jetbrains.com)
    • Eclipse (eclipse.org)
    • NetBeans (netbeans.org),

Ambiente de Desenvolvimento

  • Gerenciadores de dependências, realiza uma configuração geral e cobre o nome do projeto, seu proprietário e suas dependências de outros projetos fora da Java API.
  • Também pode configurar fases individuais do processo de construção, que são implementados como extensões.
  • Gerenciadores populares:
    • Maven (maven.apache.org)
    • Gradle (gradle.org)
    • Ant (ant.apache.org)

Abstração de Dados

  • Uma abstração é uma visão ou representação de uma entidade e inclui apenas os atributos mais significativos - Tipo de Dado definido pelo usuário.
  • Abstração de Dados possui o propósito de simplificar a complexidade de programação.
  • O conceito de abstração de dados tem suas origens no SIMULA 67, seguidas por Smalltalk, Ada, C++, Java, C#, JavaScript, Python, Ruby, etc...

Abstração de Dados

Abstração de processo.

  • Parte da abstração de dados são suas operações que são definidas como abstração de processos.
JOptionPane.
    showMessageDialog(
        null, "Acertei de novo!", 
	"Jogo dos Animais", 
        JOptionPane.DEFAULT_OPTION);

Abstração de Dados

  • Em POO a abstração de dados é melhorada por meio dos Objetos.
  • A definição dos objetos são feitas por meio de Classes e separadas em duas sessões
  1. Atributos - variáveis do tipos primitivos ou de outras abstrações
  2. Métodos - conjunto de operações para manipular os comportamentos dos objetos ()

Abstração de Dados

  • Em tempo de execução os objetos são alocados e deslocados da memória conforme a sua utilidade

  • Essa alocação e desalocação são feitas de maneira implícita pelo usuário

  •  Os tipos de dados em alguns casos podem ser parametrizados.

  • Estas construções permite que os atributos e métodos possam ser definidos através de parâmetros.

Listas<int> Listas<char> Listas<Pessoa>

Encapsulamento

  • Este é um importante recurso da abstração de dados, tanto na ocultação como na exposição dos tipos de dados.

  • O ocultamento de informação que garante confiabilidade em termos de programação para a abstração de dados.

  • Níveis de encapsulamento

  • Mínimo

  • Médio

  • Alto

  • Componentes

  • Micro services

Encapsulamento

Encapsulamento Mínimo

  • É a capacidade de expor e/ou ocultar os atributos e métodos dos Objetos para outros contexto da programação, chamados clientes.

 

package br.uem;

public class Pessoa {

	private String nome;
	private int idade;
	private char sexo;
	private Integer identidade;
	private Telefone telefone;
	// private Endereço endereco;

	public Pessoa(String nome, int idade, char sexo, Integer identidade, Telefone telefone) {
		this.nome = nome;
		this.idade = idade;
		this.sexo = sexo;
		this.identidade = identidade;
		this.telefone = telefone;
	}
	
	public String getNome() {
		return nome;
	}

Encapsulamento

Encapsulamento Médio

  • É a capacidade de expor e/ou ocultar as Classes entre si.

 

package br.uem;

import br.uem.endereco.Endereco;

public class Pessoa {

	private String nome;
	private int idade;
	private char sexo;
	private Integer identidade;
	private Telefone telefone;
	private Endereco endereco;

	public Pessoa(String nome, int idade, char sexo, Integer identidade, Telefone telefone) {
		this.nome = nome;
		this.idade = idade;
		this.sexo = sexo;
		this.identidade = identidade;
		this.telefone = telefone;
	}

Encapsulamento

Encapsulamento Alto

  • É a capacidade de expor e/ou ocultar um conjunto de classes entre si, classes irmãs.

 

Encapsulamento

Componentização

  • É a capacidade de expor e/ou ocultar um conjunto de conjuntos de classes.

 

 

Encapsulamento

Micro Serviços

  • É a capacidade de expor e/ou ocultar características de negócios entre si, conjuntos de componentes.

Livro: Microservices for Java Developers

Tipos de Dados Abstratos em Java

  • Todas as definições de tipo de dados do usuário são feita por meio de Classes
  • Um objeto na POO é uma instância dessa classe.
  • Em Java a desalocação de um objeto na memória é feita de maneira implícita pelo Garbage Collector

Tipos de Dados Abstratos em Java

  • Normalmente existe um método em toda classe definida como método construtor, esse método é responsável por entregar instâncias (objetos) desta classe.

Tipos de Dados Abstratos em Java

  • Em Java o encapsulamento mínimo e médio são definidas por meio dos modificadores de acesso que são anexadas as definições de atributos, métodos e classes

  • O encapsulamento alto é definido por meio dos pacotes (package)

  • A componentização por meio de bibliotecas (library ou lib).

Tipos de Dados Abstratos em Java

Exemplo Classe Pessoa

  • Abstração
    • atributos e métodos
    • assinatura de método
  • Encapsulamento
    • get e set
    • modificadores de acesso
    • package
    • libs (Java API)

POJO - Plain Old Java Object

Herança

A Herança em POO vem resolver alguns problemas programação procedural como: baixa produtividade, baixo reuso de software e problemas com uso somente dos tipos de dados abstratos.

Herança

  1. Nem todos os recursos existente no tipo abstrato é necessário para um novo reuso
  2. Adaptações na estrutura no tipo podem ficar complexas (todo conhecimento do tipo fica sobre responsável - projetista do tipo)
  3. Mudanças no tipo requer modificações em todos os programas clientes
  4. Definições de tipo são independentes e no mesmo nível, focado em resolver um problema específico, problemas adjacentes podem possuir objetos relacionados, tanto no mesmo nível (irmãos) como no descendência (pais e filhos)

Herança

  • A POO vem solucionar estes problemas por meio da herança, por isso é considerado o centro da POO, por ser o recurso que mais aumenta o reuso de software
  • A possibilidade de herdar os características e comportamentos, e permitir que modifique algumas entidades e adicione novas, facilita diretamente o reuso pois não impacta em mudanças no tipo de dados herdado

Herança

  • Tudo começa com um tipo de dado abstrato existente e projetar um novo tipo de dados herdando atributos e comportamentos do pré-existente
  • Uma classe que é definida por meio de herança de outra classe é chamada de classe derivada ou subclasse
  • Uma classe da qual a nova é derivada é sua classe pai, ou superclasse

Herança

Exemplo: Hierarquia Universidade

MembroDaComunidade

Empregado

Aluno

Corpo Docente

Funcionarios

Administrador

Professor

Herança

  • Diferenças mais comuns entre uma classe pai e suas subclasses:

    • Classe pai pode definir membros privados que não podem ser acessados nas subclasses, fazendo com que esse membros não sejam visíveis na subclasse

    • A subclasse pode adicionar membros (atributos e métodos) novos a subclasse

Herança

  • Diferenças mais comuns entre uma classe pai e suas subclasses:

    • A subclasse pode adicionar comportamento de um ou mais métodos herdados. Um método herdado tem o mesmo nome e a mesma assinatura. O novo método sobrescreve o método herdado, também chamado de método sobrescrito. O propósito mais comum é fornecer um comportamento específico para aquele objeto da classe derivada que não é apropriado para classe pai.​

Herança

  • Uma “desvantagem” do uso de herança é que ela cria dependências entre as classes em uma hierarquia

  • Isso vai contra a uma das vantagem de tipo abstrato de dados, que é a independência de um tipo em relação a outro

  • Porém em muitos casos as dependências (hierárquicas) espelham a realidade dos problemas reais

Herança

Outros tópicos

  • Herança múltipla.
  • Classes aninhadas:

    • Ocultamento de informações, escopo de informações

  • Sistemas Legados

Polimorfismo

  • Considere a seguinte situação: existe uma classe A que define um método que realiza uma operação em objetos da classe base. Uma segunda classe B, é definida como uma subclasse de A
  • Objetos dessa nova classe precisam de uma operação parecida com a fornecida por A mas um pouco diferente porque são levemente diferentes
  • Dessa forma um objeto da classe A também pode apontar para um objeto da classe B, tornando do se um objeto polimórfico
  • Etimologia da palavra: várias formas

  • O propósito deste recurso é permitir que os sistemas sejam melhores estendidos durante o desenvolvimento e manutenção

  • Exemplo, laço de interação em objetos polimórficos

Polimorfismo

Polimorfismo

Classe abstrata e Método abstrato

  • O projeto de uma hierarquia de heranças resultam em classes tão altas na hierarquia que começamos a definir comportamentos genéricos nas quais as subclasses devem possuir
  • Chamamos esses métodos de método abstrato que possui somente a assinatura do método e sua definição fica nas implementações das subclasses
  • Essas classes que possui métodos abstratos chamamos de classe abstrata

Portanto, pode se dizer que, o uso do polimorfismo é a evidência de maturidade no uso de dados abstratos em uma estrutura hierárquica em um projeto orientado a objetos.

Polimorfismo

Herança e Polimorfismo em Java

  • Todas as classes são filhas de Object
  • Palavra reservada final determinar que a classe ou método não pode ser herdado
  • Suporte parcial a herança múltipla usando interface com o método default
  • Método polimórfico por meio das assinaturas de métodos com tipos de interfaces e classes abstratas
  • Suporte a classes aninhadas - Inner class

Herança e Polimorfismo em Java

Associação, Agregação e Composição

Pessoa abstrata

Pessoa fisica

Pessoa jurídica

  • idade
  • sexo
  • CPF
  • nome fantasia
  • CNPJ
  • nome
  • telefones
  • endereço

Herança e Polimorfismo em Java

Associação, Agregação e Composição

Hands on

TDD princípios

  • Test Driven Development Desenvolvimento Orientado a Testes.
  • A ideia do TDD é que o desenvolvimento de software seja realizado em ciclos. 

TDD princípios

Test-Driven Development (TDD) is a technique for building software that guides software development by writing tests. It was developed by Kent Beck in the late 1990's as part of Extreme Programming. In essence you follow three simple steps repeatedly:

  • Write a test for the next bit of functionality you want to add.
  • Write the functional code until the test passes.
  • Refactor both new and old code to make it well structured.

Test-Driven Development (TDD) is a technique for building software that guides software development by writing tests. It was developed by Kent Beck in the late 1990's as part of Extreme Programming. In essence you follow three simple steps repeatedly:

TDD princípios

  • Primeiro, escreva um teste unitário que inicialmente irá falhar. O código real ainda não foi implementado;
  • Segundo, crie o código que satisfaça esse teste, ou seja: implemente a funcionalidade em questão. Essa primeira implementação deverá satisfazer imediatamente o teste ;
  • Terceiro, quando o código estiver implementado e o teste satisfeito, refatore o código para melhorar pontos como legibilidade. Logo após, execute o teste novamente. A nova versão do código também deverá passar sem que seja necessário modificar o teste escrito inicialmente.

Qual a importância do TDD?

Evitar Bugs!

Os Estados Unidos estimam que bugs de software lhes custam aproximadamente 60 bilhões de dólares por ano!

Alguns bugs de software famosos:

  • o foguete Ariane 5 explodiu por um erro de software;
  • um hospital panamenho matou pacientes pois seu software para dosagem de remédios errou.

Qual a importância do TDD?

Garantia do funcionamento do Software!

Um desenvolvimento software com TDD não diz se o software é bom ou não! Não é esseo objetivo do TDD.

Com TDD podemos afirmar que o software atende a determinados cenários implementados nos testes.

Essa é a garantia que podemos dar ao software desenvolvido usando as técnicas de TDD.

Qual a importância do TDD?

Garantia do funcionamento do Software!

Um desenvolvimento software com TDD não diz se o software é bom ou não! Não é esse o objetivo do TDD.

Com TDD podemos afirmar que o software atende a determinados cenários implementados nos testes.

Essa é a garantia que podemos dar ao software desenvolvido usando as técnicas de TDD.

Qual a importância do TDD?

Por que não testamos?

Testar é caro! Dado um sistema já desenvolvido, se uma pessoa precisasse testá-lo do começo ao fim, quanto tempo ela levaria?

Pagar um mês de uma pessoa a cada mudança feita no código é simplesmente impossível.

Os desenvolvedores também sabem que uma mudança em um trecho pode gerar problemas em outro

Qual a importância do TDD?

Qualidade

“Doutor, o senhor poderia não lavar a mão e terminar a cirurgia 15 minutos mais cedo?”

Qual desenvolvedor nunca escreveu um código de má qualidade de maneira consciente?

Quem nunca escreveu uma “gambiarra"?

Quem nunca colocou software em produção sem executar o mínimo suficiente de testes para tal?

Qual a importância do TDD?

Qualidade

Testar é divertido, pode aumentar a qualidade do software, e ajudá a identificar trechos de código que foram mal escritos
ou projetados, por meio da prática de TDD.

TDD Teste de Unidade

  • Caso de uso: Imagine um e-commerce Ao selecionar um produto, o sistema coloca no seu carrinho de compras. Ao finalizar a compra, o sistema fala com a operadora de cartão de crédito, retira o produto do estoque, dispara
    um evento para que a equipe de logística separe os produtos comprados e te envia um e-mail confirmando a compra.

TDD Teste de Unidade

  • O software que toma conta de tudo isso é complexo. Ele contém regras de negócio relacionadas ao carrinho de compras, ao pagamento, ao fechamento da compra.
  • Mas, muito provavelmente, todo esse código não está implementado em apenas um único arquivo; esse sistema é composto por diversas pequenas classes, cada uma com
    sua tarefa específica.

TDD Teste de Unidade

  • Teste de unidade testa uma única unidade do nosso sistema.
  • Em sistemas orientados a objetos, essa unidade é a classe. No exemplo do e-commerce, provavelmente existem classes como “CarrinhoDeCompras”, “Pedido”, e assim por diante.
  • O objetivo é termos baterias de testes de unidade separadas para cada uma dessas classes; cada bateria preocupada apenas com a sua classe.

TDD Teste de Unidade

Problema dos números Romanos

Os números são representados por sete diferentes símbolos.
I, unus, 1, (um)
V, quinque, 5 (cinco)
X, decem, 10 (dez)
L, quinquaginta, 50 (cinquenta)
C, centum, 100 (cem)
D, quingenti, 500 (quinhentos)
M, mille, 1.000 (mil)

TDD Teste de Unidade

Problema dos números Romanos

Para representar outros números, os símbolos são combinados entre si, começando do algarismo de maior valor e seguindo as regras:

  • Algarismos de menor ou igual valor à direita são somados ao algarismo de maior valor
  • Algarismos de menor valor à esquerda são subtraídos do algarismo de maior valor.

TDD Teste de Unidade

Problema dos números Romanos

Por exemplo, XV representa 15 (10 + 5) e o número XXVIII representa 28 (10 + 10+ 5 + 1 + 1 + 1). Última regra:

  • Nenhum símbolo pode ser repetido lado a lado por mais de 3 vezes. Por exemplo, o número 4 é representado pelo número IV (5 - 1) e não pelo número IIII.

Dado um numeral romano, o programa deve convertê-lo para o número inteiro correspondente.

TDD Teste de Unidade

Hands on

TDD Referências

TDD Aprendizado

o ciclo que foi repetido ao longo do processo de desenvolvimento foi:

  • Escrevemos um teste de unidade para uma nova funcionalidade
  • Vimos o teste falhar
  • Implementamos o código mais simples para resolver o problema
  • Vimos o teste passar
  • Melhoramos (refatoramos) nosso código quando necessário

TDD Aprendizado

Vantagens

  • Foco no teste e não na implementação
  • Código "nasce" testado
  • Simplicidade
  • Melhor reflexão sobre o design da classe
    • falta de coesão ou o excesso de acoplamento

TDD Aprendizado

Feedback mais cedo

TDD + OO hands-on

Problema do calculo de salário dos empregados da universidade

MembroDaComunidade

Empregado

Aluno

Corpo Docente

Funcionário

Administrador

Professor

TDD + OO hands-on

REGRA 1

O empregado tem um salario base inicial e a cada 12 meses recebe um aumento segundo a sua categoria sobre o salario base

  • Ex.:
    • Funcionário  8%
    • Professor 12%

TDD hands-on

REGRA 2

Professor pode ter um adicional se ele títulos

  • Ex.:
    • Especialização 2%
    • Mestrado 4%
    • Doutorado 7%
    • PhD 10%

TDD hands-on

REGRA 3

Um docente que também é administrador (chefe de departamento) tem um adicional proporcional a quantidade de cursos do seu departamento

  • Ex.: 5% por curso

TDD hands-on

REGRA 4

Caso um empregado falte no serviço, é realizado um desconto fixo + um proporcional do salario, segundo a categoria, multiplicado pela quantidade de faltas no mês.

  • Ex.: categoria funcionario 2%
    • fixo R$50,00 + (2% do salario * qnt faltas)
  • Ex.: categoria professor 3%
    • fixo R$50,00 + (3% do salario * qnt faltas)

TDD hands-on

Folha de pagamento dos empregados

O desafio é apresentar uma folha de pagamento (do mês) dos empregados da universidade (funcionários, professores e chefe de departamento)

TDD hands-on

Exemplo:

Eduardo é funcionário há 15 anos no ultimo mes ele teve uma falta. Supondo que o salario base de funcionário é de R$2000,00 e que o aumento da sua categoria em 12 meses é de 8% e o desconto da falta é de R$50,00 e a porcentagem de desconto é 2% do salario

seu salario final do mês seria:

4400 - (50,00 + 88)

4400 - 138 = 4262,00

TDD hands-on

Exemplo:

Monica é Professora, tem doutorado, da aula há 3 anos, no ultimo mes ele teve duas falta. Supondo que o salario base de professor é de R$3000,00 e que o aumento da sua categoria em 12 meses é de 12%, o adicional de doutorado é 7% e o desconto da falta é de R$50,00 e a porcentagem de desconto é 3% do salario

seu salario final do mês seria:

(4080 + 285,6) - (50,00 + 261,9) => 4365,6 - 311,9 = 4053,66

TDD hands-on

Exemplo:

Marta é Professora, tem mestrado, da aula há 5 anos e é chefe de departamento com 3 cursos, no ultimo mes ele teve uma falta. Supondo que o salario base de professor é de R$3000,00 e que o aumento da sua categoria em 12 meses é de 12%, o adicional de mestrado é 5%,  o adicional por curso é de 0,5%  e o desconto da falta é de R$50,00 e a porcentagem de desconto é 3% do salario

TDD hands-on

Exemplo:

seu salario final do mês seria:

(4800 + 252 + 720) - (50,00 + 144)

5760 - 194 = 5566,00

TDD Mock Objects

  • A ideia de um teste de unidade é realmente testar a classe de maneira isolada, sem qualquer interferência das classes que a rodeiam.
  • A vantagem desse isolamento é conseguir um maior feedback do teste em relação a classe sob teste
  • Em um teste onde as classes estão integradas, se o teste falha, qual classe gerou o problema?

TDD Mock Objects

  • Um framework de mock facilita cria classes falsas para os testes.
  • Um mock pode ser bem inteligente. É possível ensinar o mock a reagir da maneira que queremos quando um método for invocado, descobrir a quantidade de vezes que o método foi invocado pela classes e outros recursos.

BDD

Made with Slides.com