What kind of tests can I still do on that code?

Asked

Viewed 565 times

5

I’m doing a sequence of tests in a simple bank application, but I don’t know what kind of test I can do on this system to cover 100% of the code, it’s only covering 61%. I’ve done all the tests with lower values, equal and higher, I did with anonymous identification and identified, I did with anonymous identification identified with lower value, but I don’t know what kind of test to do to have 100% of the code coverage.

http://pastebin.com/EABxW0SH

The codes didn’t fit the question, so I posted them on Pastebin.org

Class of Rules

RegrasDepositoEnum.java

    package facema.regras;

    import java.math.BigDecimal;

    import facema.modelo.operacional.Deposito;
    import facema.util.StringUtils;

    public enum RegrasDepositoEnum {

        /**
         * O banco não aceita depósitos anônimos, portanto nome e CPF
         * do depositante devem ser fornecidos.
         *
         */
        DADOS_DEPOSITANTE() {
                @Override
                public boolean aplicavel(Deposito deposito) throws Exception {
                        String cpf = deposito.getDepositante().getCpf();
                        String nome = deposito.getDepositante().getNome();

                        if (StringUtils.isStringVazia(cpf) || StringUtils.isStringVazia(nome)) {
                                return false;
                        } else {
                                return true;
                        }
                }
        },

        /**
         * O valor mínimo para depósito é R$ 1,00
         * Depósitos com valores inferiores a este não serão realizados.
         * Retorna false caso o depósito tenha valor inferior a R$ 1,00, então o depósito não pode ser efetuado.
         * Retorna true em caso contrário e o depósito poderá ser efetuado.
         *
         */
        VALOR_MINIMO() {
                @Override
                public boolean aplicavel(Deposito deposito) throws Exception {
                        BigDecimal valor = deposito.getValor();

                        if (valor.compareTo(new BigDecimal("1")) < 0) {
                                return false;
                        } else {
                                return true;
                        }
                }
        };

        public abstract boolean aplicavel(Deposito deposito) throws Exception;

    }

RegrasSaqueEnum.java

    package facema.regras;

    import java.math.BigDecimal;

    import facema.modelo.banco.Conta;
    import facema.modelo.operacional.Saque;

    public enum RegrasSaqueEnum {


        /**
         * Valida se o valor do saque é maior que zero.
         * Retorna true se passar na regra.
         * Retorna false em caso contrário.
         */
        VALIDACAO_VALOR() {
                @Override
                public boolean aplicavel(Saque saque) throws Exception {
                        BigDecimal valor = saque.getValor();

                        if (valor.compareTo(BigDecimal.ZERO) > 0) {
                                return true;
                        } else {
                                return false;
                        }
                }
        },

        /**
         * Limite de R$ 200,00 por dia para saque em uma conta
         * Retorna true se passar na regra.
         * Retorna false em caso contrário.
         */
        LIMITE_DIARIO() {
                @Override
                public boolean aplicavel(Saque saque) throws Exception {
                        Conta conta = saque.getConta();
                        BigDecimal valor = saque.getValor();
                        BigDecimal limite = new BigDecimal("200.00");
                        BigDecimal saqueHoje = conta.getSaqueHoje();

                        BigDecimal saqueTotal = saqueHoje.add(valor);

                        int saqueMaiorLimite = saqueTotal.compareTo(limite);
                        if (saqueMaiorLimite > 0) {
                                return false;
                        } else {
                                return true;
                        }
                }
        },

        /**
         * O valor do saque não pode exceder o valor que o cliente possui na conta
         * Retorna true se passar na regra.
         * Retorna false em caso contrário.
         */
        LIMITE_CONTA() {
                @Override
                public boolean aplicavel(Saque saque) throws Exception {
                        Conta conta = saque.getConta();
                        BigDecimal valor = saque.getValor();

                        int saqueMaiorLimite = valor.compareTo(conta.getSaldo());
                        if (saqueMaiorLimite > 0) {
                                return false;
                        } else {
                                return true;
                        }
                }
        };

        public abstract boolean aplicavel(Saque saque) throws Exception;

    }

RegrasExtratoEnum.java

    package facema.regras;

    import java.util.Date;

    import facema.modelo.operacional.Extrato;

    public enum RegrasExtratoEnum {

        /**
         * Cliente pode solicitar extrato de um período máximo de
         * 1 ano da data inicial até a data final.
         * Caso o intervalo enre as datas inicial e final seja maior que 1 ano, retorna false e o extrato não pode ser fornecido.
         * Caso contrário, retorn true e o extrato é realizado.
         *
         */
        PERIODO_1_ANO() {
                @Override
                public boolean aplicavel(Extrato extrato) throws Exception {
                        Date dataInicial = extrato.getDataFinal();
                        Date dataFinal = extrato.getDataInicial();

                        long dif = Math.abs(dataFinal.getTime() - dataInicial.getTime());
                        long difDias = dif / (24 * 60 * 60 * 1000);

                        if (difDias > 365) {
                                return false;
                        } else {
                                return true;
                        }
                }

        },

        /**
         * O cliente tem direito a 1 extrato mensal gratuito
         * Verifica se o cliente já tirou algum extrato naquela conta gratuitamente no mês corrente.
         * Em caso positivo, o teste retorna false e o extrato deve ser cobrado.
         * Em caso negativo, o teste retorna true e o extrato deve ser gratuito.
         */
        EXTRATO_MENSAL_GRATUITO() {
                @Override
                public boolean aplicavel(Extrato extrato) throws Exception {
                        if (extrato.getConta().getExtratosMes() == 0) {
                                return true;
                        } else {
                                return false;
                        }
                }
        };

        public abstract boolean aplicavel(Extrato extrato) throws Exception;

    }

2 answers

2

Code coverage checks that all paths in your code have been traversed. This includes checking all conditional deviations.

For example:

if (valor.compareTo(new BigDecimal("1")) < 0) {
  return false;
} else {
  return true;
}

Your tests should cover both the true case and the false.

I tried to verify your code, but you did not include all classes of your system in the question.

A good tool to check the coverage of tests on your code is the Jacoco. The tool generates a report showing which part of the code is covered or not. It also adds colors to the lines of your IDE, making it easy to check.

Cores nas linhas da IDE (NetBeans).

Red lines show lines of code without unit test coverage. Green lines are codes that are covered by tests.

Relatório sobre a cobertura dos testes sobre todas as classes do pacote.

Test coverage report on all classes in the package. It is possible to observe that some classes are not covered, while others have partial coverage.

Finally, remember that coverage only means that the code has been executed. It does not guarantee that the code has actually been tested. To create effective tests, you need to create assertions that verify that methods and classes perform as expected.

Updating

I managed to run your project in Eclipse. Some considerations.

The Jacoco tool has several types of code coverage. Coverage by byte code instructions, by conditional deviations, by cyclomatic complexity, by code lines, by executed methods and by instantiated classes.

You can change which type of coverage will be used, as shown below.

Cobertura de código.

According to the image above, it is possible to verify that its coverage by lines of code is almost 100%. On this preview screen, you can select other metrics and update your tests. I checked here and some tests are missing. Take a look at the report generated in Eclipse.

Note that instruction coverage, or byte code, does not feature a reliable coverage metric. According to Jacoco: "Not all Java language constructs can be directly Compiled to corresponding byte code. In such cases the Java Compiler creates so called Synthetic code which sometimes Results in Unexpected code Coverage Results."

That is, some Java constructions are not directly transformed into byte code. The generated code is not covered, generating inconsistencies in the coverage result.

Use metrics as a method call, executed lines or cyclomatic complexity. Thus, your coverage percentage will be in line with your expectations.

  • Eclemma changes the colors Bernardo, I thought with the class of rules I could understand.

  • All lines of your code are green?

  • Yes. I don’t know what kind of test can be done on it anymore.

  • Does the report show 100% coverage? Where are you seeing only 61% coverage? It is possible that the tool is not calculating correctly, sometimes this kind of thing happens.

  • I’ll send the other classes.

  • I’ll copy it to Dropbox for you to see, it’s a lot of classes.

  • Check it out! https://www.dropbox.com/sh/07y16ghjr5bz6oo/ADlMFKHdMa_yMXs2rciKDxia?dl=0

  • I updated the answer, take a look.

  • You executed on Jacoco?

  • Yes, I executed in Jacoco.

Show 5 more comments

1

Here are some suggestions:

In DADOS_DEPOSITANTE(): tried to put invalid CPF in the value, but validated in the structure? Example 999.999.999.99, try this with "0" because not all masks treat CPF with 11 "0". He tested the input of letters instead of the CPF. Have you tested the size of the name field? How many characters does it hold. Tested fill the name field with spaces by pressing the space bar? It will not be null value, only blank value, this error almost no programmer treats.

VALOR_MINIMO(): Tested negative value? Letters? Special characters?

Just looking at this code, my mind has been pounding with tests that can be performed... Try putting an html tag in the fields and type enter and so on.

  • Bigdecimal does not accept letters Paulo.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.