Qualidade
em
Testes de Software
➔Sobre o instrutor;
➔Objetivo;
➔Introdução aos testes;
➔Tipos, Práticas e Padrões
Agenda
Instrutor
➔O que vou ser quando crescer;
➔Bacharelado - UTFPR/MD;
➔Mestrado em SI - IPB/PT;
➔Especialização em IA * - UFPR;
➔Fanático por Tecnologia.
Objetivo
➔Qual o propósito ?
Introdução
➔O que são testes ?
➔O que fazem ?
➔Onde vivem (ou deveriam viver)
?
O que são
Os testes de software são instrumentos utilizados para validar o funcionamento de um
software e tem por propósito mostrar a presença de bugs, e não a ausência.
Para provar que algo é verdade, significa que todas as coisas que são negações dessa sua
afirmação, tem que ser mentira. Se uma delas falharem, a sua afirmação não é verdade. Tem certos
casos que é mais fácil você provar uma inverdade do que um fato, ou seja, prova por refutação.
Exemplo:
Afirmação 1 - Agora está ensolarado no Brasil todo.
FATO 1 - Em todo o Brasil o céu está sem nuvens
FATO 2 - São Paulo é no Brasil
FATO 3 - São Paulo está nublado
O que fazem
Fornecem insumos para considerarmos que um programa está suficientemente correto para
o que queremos.
Não é possível eu provar que meu programa não tem bugs se eu não consigo testar todos os
cenários possíveis.
Eu posso afirmar que um programa é incorreto por meio de testes, mas meu teste não pode
afirmar que este programa está correto.
Exemplo:
Cliente solicita um software que retorna o valor de PI.
Onde vivem
Testes unitários
Testes de serviço
E2E
Exemplo Tela 1 - Telefone
Campos:
Código do País
Tipo: Numérico
Regras:
Deve permitir apenas números
Deve ter no máximo 3 dígitos
Obrigatório
Deve ter uma máscara que acrescente o + antes do número (+351, +55)
Código de Area
Tipo: Numérico
Regras:
Deve permitir apenas numeros
Deve ter no máximo 2 dígitos
Obrigatório para alguns países
Telefone
Tipo: Numérico
Regras:
Deve permitir apenas números
Deve permitir 8 ou 9 caracteres
Deve ter uma máscara que acrescente o - (Ex: 9 9999-9999 ou 9999-9999)
Exemplo Tela 2 - Nome
Campos:
Nome Completo do Cliente
Tipo: Texto
Regras:
Deve um tamanho máximo 80 caracteres
Deve permitir apenas letras do alfabeto, incluindo acentuação.
Deve ter pelo menos 2 Palavras (Pafúncio Geno)
Exemplo Tela 3 - Número do Documento
Botao Cadastrar
Campos:
CPF do cliente
Tipo: Numérico
Regras:
Deve ter um tamanho máximo de 11 caracteres
Deve permitir que seja inserido apenas números
Deve ter uma máscara que acrescente hífens e pontos finais.
(Ex: 000.000.000-00)
Deve ser um CPF válido seguindo o algoritmo validar de CPF
Como testar ?
● Coda, builda, testa.
○ Se der erro
■ Coda, builda, testa.
■ Se der erro,
● Coda, builda, testa….
○ Se passar, vai pra proxima feature
● Proxima Feature
■ Coda, builda, testa
● Se der erro,
○ Coda, builda, testa….
● Coda teste
○ Coda funcionalidade
■ Executa teste
■ Se der erro,
● Refatora,
■ ...
Como colocar isso em uma pipeline automatizada ?
Quais cenários foram testados ?
Quais evidências que esses cenários foram testados ?
Como colocar isso em uma pipeline automatizada ?
Quais cenários foram testados ?
Quais evidências que esses cenários foram testados ?
Feature Request
Tela 3 - Número do Documento
Botao Cadastrar
Campos:
CPF ou CNPJ do cliente
Tipo: Numérico
Regras:
Deve ter 11 ou 14 caracteres.
Deve permitir que seja inserido apenas números
Deve ter uma máscara que acrescente hífens e pontos finais
(Ex: 000.000.000-00) para CPF ou hífens, pontos finais e barras
para CNPJ (00.000.000/0000-00)
Deve ser um CPF ou CNPJ válido seguindo o algoritmo validador
de CPF/CNPJ
Como testar ?
● Coda, builda, testa.
○ Se der erro
■ Coda, builda testa,
■ Se der erro,
● Coda, builda, testa….
○ Se passar, vai pra proxima feature
● Proxima Feature
■ Coda, builda, testa
● Se der erro,
○ Coda, builda, testa….
● Coda teste
○ Coda funcionalidade
■ Executa teste
■ Se der erro,
● Refatora,
■ ...
Como colocar isso em uma pipeline automatizada ?
Quais cenários foram testados ?
Quais evidências que esses cenários foram testados ?
Como colocar isso em uma pipeline automatizada ?
Quais cenários foram testados ?
Quais evidências que esses cenários foram testados ?
Testes dos Testes
Mas se o teste é um código e quem escreve o teste unitário é quem escreve o
próprio código, quem testa o teste, quem garante a qualidade dos testes ?
Coverage
Mede a abrangência do teste em um código testado.
Em outras palavras, ajuda a descobrir quais trechos de código não estão sendo
testados.
Neste caso, um teste mal feito pode ter coberto um cenário, portanto, a
cobertura de testes não mede a qualidade do seu teste, mas já é um bom início,
pois um código não coberto é pior que um teste mal feito.
Um teste sem validações ainda pode descobrir NullPointers.
Em um dos artigos escritos por Martin Fowler sobre testes, ele indica que o ideal
é ter entre 80 e 90 de cobertura de código, e ainda diz que desconfia de
softwares com 100% de cobertura, pois isso pode induzir desenvolvedores a ter
uma prática de focar sempre em aumentar o coverage ao invés de escrever
testes de qualidade.
Análise de Código
➔Code Review Humano;
➔Sonar;
➔Code Guru;
➔Gerrit;
➔Etc.
Alguns Tipos de Testes
➔Teste Unitário;
➔Teste de Integração;
➔Teste Regressivo;
➔Teste Automatizado;
➔Teste de Mutação;
➔Teste E2E.
Testes Unitários
➔O que são ?
➔Práticas
➔Padrões
Teste Unitário - Arrange
@Test
fun shouldReturnValidWhenDocumentHas14Digits() {
val document = "12345678000115"
}
@Test
fun shouldThrowInvalidDocumentExceptionWhenDocumentHasMoreThan14Digits() {
val document = "12345678000115222"
}
@Test
fun shouldThrowInvalidDocumentExceptionWhenDocumentHasLetters() {
val document = "abcdef12345678"
}
Teste Unitário - Act
fun shouldReturnTrueWhenDocumentHas14Digits() {
val document = "12345678000115"
validateDocument.execute(document)
}
fun shouldThrowInvalidDocumentExceptionWhenDocumentHasMoreThan14Digits() {
val document = "12345678000115222"
validateDocument.execute(document)
}
fun shouldThrowInvalidDocumentExceptionWhenDocumentHasLetters() {
val document = "abcdef12345678"
validateDocument.execute(document)
}
fun shouldNotPerformDocumentValidationWhenValidationDocumentFeatureIsDisable() {
val document = "12345678000115222"
when(featureFlag.documentValidation).thenReturn(false)
validateDocument.execute(document)
}
Teste Unitário - Assert
fun shouldReturnTrueWhenDocumentHas14Digits() {
val document = "12345678000115"
result = validateDocument.execute(document)
verify(validateDocument, times(1)).execute(document)
assertTrue(result)
}
@Test(expected=InvalidDocumentException::class)
fun shouldThrowInvalidDocumentExceptionWhenDocumentHasMoreThan14Digits() {
val document = "12345678000115222"
result = validateDocument.execute(document)
}
fun shouldReturnTrueWhenValidationDocumentFeatureIsDisable() {
val document = "12345678000115222"
when(featureFlag.documentValidation).thenReturn(false)
result = validateDocument.execute(document)
verify(validateDocument, times(1)).execute(any())
assertTrue(result)
}
Teste Unitário
Como colocar isso em uma pipeline automatizada ?
Quais cenários foram testados ?
Quais evidências que esses cenários foram testados ?
Teste de Integração
Quando uma aplicação necessita consumir (integrar) serviços de outras aplicações, por exemplo:
um App consumindo uma API Rest;
um Microserviço A consumindo recursos de um Microserviço B;
uma aplicação consumindo serviços da AWS,
um banco de dados
Teste de Integração
@Test
fun shouldReturnOkWhenCommunicationPerformedSuccessfully() {
val result = testRestTemplate.getForEntity("http://numbersapi.com/random/trivia?json",
RandomNumberResponseDTO::class.java)
val obj: RandomNumberResponseDTO? = result.body;
Assert.assertEquals(HttpStatus.OK, result.statusCode)
Assert.assertTrue(result.hasBody())
Assert.assertTrue(obj?.found!!)
Assert.assertNotNull(obj.text)
Assert.assertNotNull(obj.number)
}
Teste Regressivo
Velocidade;
Otimização de Tempo;
Validação de Impacto.
Teste de Mutação
Quem testa os testes ? Como identificar malandrinhos que testam sem asserts ?
Escrevemos um outro teste para testar o teste escrito ?
Como funciona ?
Teste de Mutação
if (tamanhoMaximo <= 50) {
return
}
Exemplo de uma mutação
if (tamanhoMaximo < 50) {
return
}
Teste de Mutação
@Test
fun shouldPerformSuccessfullyWhenValueLenghtIs5() {
val textToBeValidated = "11122"
validateLength.execute(textToBeValidated)
verify(validateLength, times(1)).execute(any())
}
@Test(expected = InvalidDocumentException::class)
fun shouldReturnErrorWheValueLengthIs51() {
val textToBeValidated = "11111111110000000000333333333344444444445555555555#"
validateLength.execute(textToBeValidated)
verify(validateLength, times(1)).execute(any())
}
Teste de Mutação
Teste de Mutação
@Test
fun shouldPerformSuccessfullyWhenValueLenghtIs50() {
val textToBeValidated = "11111111110000000000333333333344444444445555555555"
maxLengthX.execute(textToBeValidated)
}
Teste de Mutação
Dúvidas ?
Sugestões?
Críticas ?

Qualidade em Testes de Software

  • 1.
  • 2.
    ➔Sobre o instrutor; ➔Objetivo; ➔Introduçãoaos testes; ➔Tipos, Práticas e Padrões Agenda
  • 3.
    Instrutor ➔O que vouser quando crescer; ➔Bacharelado - UTFPR/MD; ➔Mestrado em SI - IPB/PT; ➔Especialização em IA * - UFPR; ➔Fanático por Tecnologia.
  • 4.
  • 5.
    Introdução ➔O que sãotestes ? ➔O que fazem ? ➔Onde vivem (ou deveriam viver) ?
  • 6.
    O que são Ostestes de software são instrumentos utilizados para validar o funcionamento de um software e tem por propósito mostrar a presença de bugs, e não a ausência. Para provar que algo é verdade, significa que todas as coisas que são negações dessa sua afirmação, tem que ser mentira. Se uma delas falharem, a sua afirmação não é verdade. Tem certos casos que é mais fácil você provar uma inverdade do que um fato, ou seja, prova por refutação. Exemplo: Afirmação 1 - Agora está ensolarado no Brasil todo. FATO 1 - Em todo o Brasil o céu está sem nuvens FATO 2 - São Paulo é no Brasil FATO 3 - São Paulo está nublado
  • 7.
    O que fazem Forneceminsumos para considerarmos que um programa está suficientemente correto para o que queremos. Não é possível eu provar que meu programa não tem bugs se eu não consigo testar todos os cenários possíveis. Eu posso afirmar que um programa é incorreto por meio de testes, mas meu teste não pode afirmar que este programa está correto. Exemplo: Cliente solicita um software que retorna o valor de PI.
  • 8.
  • 9.
    Exemplo Tela 1- Telefone Campos: Código do País Tipo: Numérico Regras: Deve permitir apenas números Deve ter no máximo 3 dígitos Obrigatório Deve ter uma máscara que acrescente o + antes do número (+351, +55) Código de Area Tipo: Numérico Regras: Deve permitir apenas numeros Deve ter no máximo 2 dígitos Obrigatório para alguns países Telefone Tipo: Numérico Regras: Deve permitir apenas números Deve permitir 8 ou 9 caracteres Deve ter uma máscara que acrescente o - (Ex: 9 9999-9999 ou 9999-9999)
  • 10.
    Exemplo Tela 2- Nome Campos: Nome Completo do Cliente Tipo: Texto Regras: Deve um tamanho máximo 80 caracteres Deve permitir apenas letras do alfabeto, incluindo acentuação. Deve ter pelo menos 2 Palavras (Pafúncio Geno)
  • 11.
    Exemplo Tela 3- Número do Documento Botao Cadastrar Campos: CPF do cliente Tipo: Numérico Regras: Deve ter um tamanho máximo de 11 caracteres Deve permitir que seja inserido apenas números Deve ter uma máscara que acrescente hífens e pontos finais. (Ex: 000.000.000-00) Deve ser um CPF válido seguindo o algoritmo validar de CPF
  • 12.
    Como testar ? ●Coda, builda, testa. ○ Se der erro ■ Coda, builda, testa. ■ Se der erro, ● Coda, builda, testa…. ○ Se passar, vai pra proxima feature ● Proxima Feature ■ Coda, builda, testa ● Se der erro, ○ Coda, builda, testa…. ● Coda teste ○ Coda funcionalidade ■ Executa teste ■ Se der erro, ● Refatora, ■ ... Como colocar isso em uma pipeline automatizada ? Quais cenários foram testados ? Quais evidências que esses cenários foram testados ? Como colocar isso em uma pipeline automatizada ? Quais cenários foram testados ? Quais evidências que esses cenários foram testados ?
  • 13.
    Feature Request Tela 3- Número do Documento Botao Cadastrar Campos: CPF ou CNPJ do cliente Tipo: Numérico Regras: Deve ter 11 ou 14 caracteres. Deve permitir que seja inserido apenas números Deve ter uma máscara que acrescente hífens e pontos finais (Ex: 000.000.000-00) para CPF ou hífens, pontos finais e barras para CNPJ (00.000.000/0000-00) Deve ser um CPF ou CNPJ válido seguindo o algoritmo validador de CPF/CNPJ
  • 14.
    Como testar ? ●Coda, builda, testa. ○ Se der erro ■ Coda, builda testa, ■ Se der erro, ● Coda, builda, testa…. ○ Se passar, vai pra proxima feature ● Proxima Feature ■ Coda, builda, testa ● Se der erro, ○ Coda, builda, testa…. ● Coda teste ○ Coda funcionalidade ■ Executa teste ■ Se der erro, ● Refatora, ■ ... Como colocar isso em uma pipeline automatizada ? Quais cenários foram testados ? Quais evidências que esses cenários foram testados ? Como colocar isso em uma pipeline automatizada ? Quais cenários foram testados ? Quais evidências que esses cenários foram testados ?
  • 15.
    Testes dos Testes Masse o teste é um código e quem escreve o teste unitário é quem escreve o próprio código, quem testa o teste, quem garante a qualidade dos testes ?
  • 16.
    Coverage Mede a abrangênciado teste em um código testado. Em outras palavras, ajuda a descobrir quais trechos de código não estão sendo testados. Neste caso, um teste mal feito pode ter coberto um cenário, portanto, a cobertura de testes não mede a qualidade do seu teste, mas já é um bom início, pois um código não coberto é pior que um teste mal feito. Um teste sem validações ainda pode descobrir NullPointers. Em um dos artigos escritos por Martin Fowler sobre testes, ele indica que o ideal é ter entre 80 e 90 de cobertura de código, e ainda diz que desconfia de softwares com 100% de cobertura, pois isso pode induzir desenvolvedores a ter uma prática de focar sempre em aumentar o coverage ao invés de escrever testes de qualidade.
  • 17.
    Análise de Código ➔CodeReview Humano; ➔Sonar; ➔Code Guru; ➔Gerrit; ➔Etc.
  • 18.
    Alguns Tipos deTestes ➔Teste Unitário; ➔Teste de Integração; ➔Teste Regressivo; ➔Teste Automatizado; ➔Teste de Mutação; ➔Teste E2E.
  • 19.
    Testes Unitários ➔O quesão ? ➔Práticas ➔Padrões
  • 20.
    Teste Unitário -Arrange @Test fun shouldReturnValidWhenDocumentHas14Digits() { val document = "12345678000115" } @Test fun shouldThrowInvalidDocumentExceptionWhenDocumentHasMoreThan14Digits() { val document = "12345678000115222" } @Test fun shouldThrowInvalidDocumentExceptionWhenDocumentHasLetters() { val document = "abcdef12345678" }
  • 21.
    Teste Unitário -Act fun shouldReturnTrueWhenDocumentHas14Digits() { val document = "12345678000115" validateDocument.execute(document) } fun shouldThrowInvalidDocumentExceptionWhenDocumentHasMoreThan14Digits() { val document = "12345678000115222" validateDocument.execute(document) } fun shouldThrowInvalidDocumentExceptionWhenDocumentHasLetters() { val document = "abcdef12345678" validateDocument.execute(document) } fun shouldNotPerformDocumentValidationWhenValidationDocumentFeatureIsDisable() { val document = "12345678000115222" when(featureFlag.documentValidation).thenReturn(false) validateDocument.execute(document) }
  • 22.
    Teste Unitário -Assert fun shouldReturnTrueWhenDocumentHas14Digits() { val document = "12345678000115" result = validateDocument.execute(document) verify(validateDocument, times(1)).execute(document) assertTrue(result) } @Test(expected=InvalidDocumentException::class) fun shouldThrowInvalidDocumentExceptionWhenDocumentHasMoreThan14Digits() { val document = "12345678000115222" result = validateDocument.execute(document) } fun shouldReturnTrueWhenValidationDocumentFeatureIsDisable() { val document = "12345678000115222" when(featureFlag.documentValidation).thenReturn(false) result = validateDocument.execute(document) verify(validateDocument, times(1)).execute(any()) assertTrue(result) }
  • 23.
    Teste Unitário Como colocarisso em uma pipeline automatizada ? Quais cenários foram testados ? Quais evidências que esses cenários foram testados ?
  • 24.
    Teste de Integração Quandouma aplicação necessita consumir (integrar) serviços de outras aplicações, por exemplo: um App consumindo uma API Rest; um Microserviço A consumindo recursos de um Microserviço B; uma aplicação consumindo serviços da AWS, um banco de dados
  • 25.
    Teste de Integração @Test funshouldReturnOkWhenCommunicationPerformedSuccessfully() { val result = testRestTemplate.getForEntity("http://numbersapi.com/random/trivia?json", RandomNumberResponseDTO::class.java) val obj: RandomNumberResponseDTO? = result.body; Assert.assertEquals(HttpStatus.OK, result.statusCode) Assert.assertTrue(result.hasBody()) Assert.assertTrue(obj?.found!!) Assert.assertNotNull(obj.text) Assert.assertNotNull(obj.number) }
  • 26.
    Teste Regressivo Velocidade; Otimização deTempo; Validação de Impacto.
  • 27.
    Teste de Mutação Quemtesta os testes ? Como identificar malandrinhos que testam sem asserts ? Escrevemos um outro teste para testar o teste escrito ? Como funciona ?
  • 28.
    Teste de Mutação if(tamanhoMaximo <= 50) { return } Exemplo de uma mutação if (tamanhoMaximo < 50) { return }
  • 29.
    Teste de Mutação @Test funshouldPerformSuccessfullyWhenValueLenghtIs5() { val textToBeValidated = "11122" validateLength.execute(textToBeValidated) verify(validateLength, times(1)).execute(any()) } @Test(expected = InvalidDocumentException::class) fun shouldReturnErrorWheValueLengthIs51() { val textToBeValidated = "11111111110000000000333333333344444444445555555555#" validateLength.execute(textToBeValidated) verify(validateLength, times(1)).execute(any()) }
  • 30.
  • 31.
    Teste de Mutação @Test funshouldPerformSuccessfullyWhenValueLenghtIs50() { val textToBeValidated = "11111111110000000000333333333344444444445555555555" maxLengthX.execute(textToBeValidated) }
  • 32.
  • 33.