Skip to content

Instantly share code, notes, and snippets.

@rafaelpontezup
Last active November 12, 2024 18:34
Show Gist options
  • Save rafaelpontezup/ecba938670eb13f876bd279e898b84af to your computer and use it in GitHub Desktop.
Save rafaelpontezup/ecba938670eb13f876bd279e898b84af to your computer and use it in GitHub Desktop.
Quantos e quais cenarios/casos de testes você enxerga para o código da classe ParceladorDeFatura? (adiciona resposta nos comentarios)
package br.com.zup.edu.certificacoes.testing.parcelador;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
public class ParceladorDeFatura {
public static final BigDecimal VALOR_MINIMO_FATURA = new BigDecimal("100");
public static final BigDecimal VALOR_MAXIMO_FATURA = new BigDecimal("100000"); // UPDATED at 2024-10-24
public List<BigDecimal> parcela(BigDecimal valor, int quantidadeDeParcelas) {
if (valor == null) {
throw new FaturaInvalidaException("Valor da fatura não pode ser nula");
}
if (valor.compareTo(VALOR_MINIMO_FATURA) < 0) {
throw new FaturaInvalidaException("Valor da fatura muito baixo para parcelamento");
}
// UPDATED at 2024-10-24
if (valor.compareTo(VALOR_MAXIMO_FATURA) > 0) {
throw new FaturaInvalidaException("Valor da fatura acima do valor máximo para parcelamento");
}
if (quantidadeDeParcelas < 2 || quantidadeDeParcelas > 10) {
throw new FaturaInvalidaException("Número de parcelas deve estar entre 2 e 10");
}
BigDecimal numeroDeParcelas = BigDecimal.valueOf(quantidadeDeParcelas);
BigDecimal valorDaParcela = valor.divide(numeroDeParcelas, 2, RoundingMode.DOWN);
List<BigDecimal> parcelas = new ArrayList<>();
for (int i = 0; i < quantidadeDeParcelas - 1; i++) {
parcelas.add(valorDaParcela);
}
// adiciona resto na ultima parcela
BigDecimal resto = valor.subtract(valorDaParcela.multiply(numeroDeParcelas));
parcelas.add(valorDaParcela.add(resto));
return parcelas;
}
}
@jacksonmotazup
Copy link

Confesso que tenho dificuldades para bater o olho e dizer quantos, geralmente vou fazendo descobrindo e tentando cobrir todas as possiblidades.
1 - para o primeiro if
3 - para o segundo if ( com numero acima de 0, com 0 e com menor que 0)
6 - para o terceuri if( parecido com o de cima mas com duas condicionais OR)

Alguns para o valor, não sei exatamente quantos nesse caso mas pelo menos 3 por conta do arredondamento e valores. talvez testes que explorem valores aleatórios pra ajudar a descobrir bugs, tem uma ferramenta pra isso mas esqueci o nome xD
Mas acho que pelo menos 13 kkkkk

@yurioliveirazup
Copy link

yurioliveirazup commented Jan 11, 2023

Cenário 1: Valor da Fatura ser nulo
Cenário 2: Valor a ser pago ser menor que o valor mínimo
Cenário 3: Quantidade de parcelas ser menor que 2
Cenário 4: Quantidade de parcelas ser maior que 10
Cenário 5: Happy path para quando tem resto e quando não tem resto

@jordisilvazup
Copy link

jordisilvazup commented Jan 11, 2023

Eu escreveria os seguintes cenários:

  1. O valor da parcela não deve ser nulo
  2. O valor da parcela não deve ser inferior ao valor mínimo da fatura.
  3. A quantidade de parcelas não deve ser inferior a 2 ou superior a 10 ( com varias entradas)
  4. Deve parcelar um valor acima do valor mínimo de fatura, com parcelas entre 2 e 10
  5. Deve parcelar um valor onde o resto seja diferente de zero

Copy link

ghost commented Jan 11, 2023

  1. Valor da fatura nulo
  2. Valor muito baixo para parcelamento (um teste com valor menor que o mínimo e um com o mínimo valor - boundary)
  3. quantidadeDeParcelas 1, 2, 10, 11 (boundary)
  4. MCDC if (3 casos, já cobertos no item 3)
  5. for - não gera coleção vazia (já coberto no item 3)
  6. for - não gera coleção com um elemento (ou seja, parcela única)
  7. Parcelamento com resto zero e maior que zero
    Acho que somando tudo aqui daria 11 casos, mínimo (talvez eu fizesse mais com mesmo cenário mas asserts diferentes, onde eles significariam coisas diferentes).

@alenvieirazup
Copy link

Enxergo pelo menos 6 cenários:

  • 4 para exceções: valor nulo da fatura, valor de fatura menor que o mínimo e os limites das quantidades de fatura.
  • 2 para checar os valores das parcelas, quando o valor da fatura é dividível pelo número de parcelas e os valores da parcela são iguais e o outro quando não é dividível e apenas o último valore da fatura é diferente.

Exemplos:

  1. Para verificar se com o valor da fatura nulo, é acionado uma exceção de fatura invalida pelo valor nulo.
  2. Para verificar se com o valor da fatura menor que o mínimo, é acionado uma exceção de fatura invalida para parcelamento.
  3. Para verificar se com a quantidade de parcela menor que 2, é acionado uma exceção de fatura invalida para a quantidade de parcela.
  4. Para verificar se com a quantidade de parcela maior que 10, é acionado uma exceção de fatura invalida para a quantidade de parcela.
  5. Para verificar se com a quantidade de parcela igual a 2 com um valor dividível por 2, checar que as parcelas estão com o mesmo valor.
  6. Para verificar se com a quantidade de parcela igual a 10 com um valor não dividível por 10, e checar com a exceção da última se que as parcelas estão com o mesmo valor.

@lucassampaiozup
Copy link

  1. Valor nulo
  2. Valor negativo
  3. Valor da fatura baixo para o parcelamento
  4. Quantidade de parcelas abaixo de 2
  5. Quantidade de parcelas maior que 10
  6. Quantidade de parcelas dentro do valor esperado
  7. Valor e parcelas que desse divisão exata e tudo certo
  8. Valor e parcelas que desse quebrado e gerasse resto

@alexandreaquiles
Copy link

alexandreaquiles commented Jan 11, 2023

  1. valor nulo => Exception
  2. valor menor que o mínimo => Exception
  3. valor maior que mínimo e quantidadeDeParcelas com 1 => Exception
  4. valor maior que mínimo e quantidadeDeParcelas com 1 => Exception
  5. valor maior que mínimo e quantidadeDeParcelas com 11 => Exception
  6. valor igual ao mínimo e quantidadeDeParcelas com 2 e sem resto => verifica list
  7. valor maior que mínimo e quantidadeDeParcelas com 2 e sem resto => verifica list
  8. valor maior que mínimo e quantidadeDeParcelas com 10 e sem resto => verifica list
  9. valor maior que mínimo e quantidadeDeParcelas entre 2 e 10 e sem resto => verifica list
  10. valor maior que mínimo e quantidadeDeParcelas entre 2 e 10 e com resto => verifica list

@asouza
Copy link

asouza commented Jan 11, 2023

  1. Entrou no primeiro if (valor nulo)
  2. Entrou no segundo if (valor anterior ao minimo)
  3. Entrou no terceiro if pelo lado esquerdo (quantidade = 1)
  4. Entrou no terceiro if pelo lado direito (quantidade = 11)
  5. Entrou no loop uma vez(quantidade = 2)
  6. Entrou no loop rodando duas ou mais vez (quantidade = 10)
  7. Self testing no final para verificar que tem "quantidade" no array

Aí poderia exercitar mais vezes

@rafaelpontezup
Copy link
Author

rafaelpontezup commented Jan 11, 2023

Eu enxerguei 6 cenários/casos de testes:

  1. Entrou no primeiro if (valor nulo);
  2. Entrou no segundo if (valor menor que 100);
  3. Entrou no terceiro if pelo lado esquerdo (quantidade = 1);
  4. Entrou no terceiro if pelo lado direito (quantidade = 11);
  5. Happy-path com valor redondo (valor = 100 e quantidade = 2);
  6. Happy-path com valor quebrado gerando resto (valor = 100 e quantidade = 3);

Contudo....
Podemos resumir em 4 cenários/casos se considerarmos classes de equivalência, ou seja, podemos juntar na mesma classe itens 3 e 4, e também itens 5 e 6.

@mauricioaniche
Copy link

A implementação do método é bem direta. Meu primeiro foco seria testar cada um dos caminhos possíveis nesse método, que são bem claros se vc olhar os ifs do código. Aproveito e sempre que visito um if, olho pro valor de entrada do usuário que ele usa, e analiso o domínio de entrada daquele valor:

  • Linha 14: Valor nulo, teste espera uma exceção
  • Linha 18: Valor menor que 0, teste espera uma exceção, e valor igual a 0 (fronteira da condição), programa não quebra (Não quebra mesmo, me parece estranho parcelar 0 reais...)
  • Linha 18: Me chama a atenção o fato de não ter limite superior para valor. Se esse for mesmo o caso, eu testaria com um valor bem alto (MAX_INT) pra garantir que tudo continua funcionando.
  • Linha 22: Quantidade de parcela igual a 2 e igual a 1 (1 não funciona, 2 funciona). Dois testes aqui pra exercitar a fronteira da condição.
  • Linha 22: Quantidade de parcela igual a 10 e igual a 11 (10 funciona, 11 não funciona). Dois testes aqui pra exercitar a fronteira.

A partir daqui o método tem um caminho único. Olhando a implementação, entendo que o código divide o total entre o número de parcelas pedido, adiciona qualquer diferença na última parcela. Regras de arredondamento são duas casas decimais e arredondar pra baixo.

Pensando nas principais variáveis que estão em jogo aqui:

  • Última parcela: Última parcela que seja um pouco maior do que as anteriores, e última parcela que seja igual as anteriores. Pensaria aqui também se é possível que a última parcela seja um pouco menor, mas como arredondamos pra baixo, acho que não é possível.
  • Arredondamento: caso onde o número seja forçado a arredondar pra baixo
  • Número de parcelas: 2, 10 (limites), um número no meio ("in point") qualquer apenas pra garantir.

Não consigo pensar em mais nada. Agora é só transformar esses casos de teste em testes automatizados. Se rodar cobertura de código aqui, espero que bata 100%. Se não bater, olhar o que faltou.

Esse método é um excelente caso também para property-based tests. A propriedade é direta, e bem fácil de ser implementada: dado qualquer número de parcelas entre 2 e 10, e qualquer valor maior do que zero, a soma das parcelas geradas tem que ser igual ao valor inicial.

PS: Vc não precisa de testes repetidos. O teste com 2 parcelas que sugeri no começo pode ser o mesmo teste que sugeri quando explorei o "caminho feliz" do método. Quando estou pensando nos casos de testes, não me preocupo muito em encontrar "o menor conjunto de testes", a limpeza acontece depois.

@kewers
Copy link

kewers commented Jan 16, 2023

A : BigDecimal
B : Int
1. A == null ==> Exception
2. A < 100   ==> Exception
3. B < 2     ==> Exception
4. B > 10    ==> Exception
5. Para todo (A : BigDecimal) e (B : Int), onde A!= null, e A >= 100, e B >= 2, e B <= 10, 
    somaLista(parcela(A,B)) == A
    length(parcela(A,B)) == B

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment