Nesse treinamento vamos começar falando de uma aplicação de leilão. Vamos ter lances, usuários e o leilão propriamente dito. Na hora de avaliarmos leilões nós vamos ver a necessidade de criarmos testes para isso, vamos entender o motivo de ter testes automatizados, vamos ver o que é um teste automatizado e o que ele precisa ter para ser considerado um teste automatizado.
Além disso tudo, obviamente, vamos utilizar ferramentas profissionais de testes automatizados. Aqui vamos utilizar uma conhecida como Catch 2, vamos ver como configurá-lo, como instalá-lo e vamos ver que é muito simples.
Nesse processo vamos aprender coisas como classes de equivalência, vamos organizar nossos testes e vamos otimizar o tempo de compilação dos nossos testes. Vamos aprender sobre TDD (Test Driven Development). Vamos aprender bastante coisas durante esse treinamento!
Acho válido citar que durante esse treinamento vamos focar em um tipo de teste, conhecido como Teste de Unidade. Isso quer dizer de forma resumida que um teste de unidade é aquele teste que verifica o funcionamento da menor unidade possível do código. Por exemplo: uma função, um método, uma classe, o menor possível para conseguir executar algo funcional e verificar a saída daquilo, verificar o comportamento.
Teste de unidade é o tipo de teste, segundo o que podemos ver nessa pirâmide, é o tipo de teste que mais devemos ter em um projeto real. Porque o teste de unidade é rápido e é confiável, nós sabemos que ele não muda tanto conforme o sistema cresce.
Já um teste de integração depende de integração com outras coisas. Por exemplo: o seu programa chama um outro executável, salvo em um arquivo. Se esse executável não estiver disponível, o seu teste falha; se o arquivo tentar ser escrito em um momento que você não tem permissão, o teste falha. Ele é mais propenso à falha, além de ser mais lento.
E testes end-to-end são testes que realizam as verificações pela perspectiva do usuário. Se é um teste de um jogo, você vai abrir a tela do jogo e realizar alguns comandos; se é um editor de texto, por exemplo, você vai abrir a janela do editor de texto e clicar em alguns botões. Se um botão muda de lugar todo o teste quebra. Esse tipo de teste é mais lento e mais propenso à falha.
Se você conhece o desenho do papa-léguas e coiote, você entendeu essa analogia, basicamente é isso. Em um cenário real você deve ter muitos testes de unidade, alguns testes de integração e só deve ter testes ponta a ponta para o cenário mais crítico da sua aplicação.
Nesse treinamento nós vamos focar em teste de unidade, vamos aprender técnicas de teste e ferramentas; enfim, tudo isso que eu já falei. Te espero no próximo vídeo para você conhecer a aplicação que vamos testar!
Boas-vindas de volta! Vamos conhecer o ambiente, o sistema em que vamos trabalhar.
Eu disponibilizei para vocês, no primeiro exercício desse treinamento, o arquivo que vai ter todas as classes desse projeto. Você só precisa criar um projeto novo na sua IDE, seja lá qual IDE você estiver utilizando, e importar esses arquivos como já fizemos em treinamentos anteriores.
Vamos dar uma olhada aqui no que temos. Primeiro, temos uma classe que representa um usuário. O usuário é quem vai dá um lance no leilão, no nosso sistema de leilão. Por enquanto ele só tem o nome; se alguma coisa a mais for necessária, posteriormente adicionaremos.
Aqui é a implementação do usuário, é só a inicialização do construtor e um getter, nada além disso.
E temos a representação de um lance. Um lance tem o usuário que deu esse lance e o valor do lance em si. Tudo o que precisamos são essas informações. De novo, se precisarmos de alguma a mais, no futuro nós veremos.
A implementação do lance só tem a inicialização dos seus valores e um getter do valor. Você pode me falar: "Vinicius, não tem nenhum getter do usuário aí." Se precisarmos desses getter, aí implementaremos - provavelmente vamos precisar. Enquanto ele não for necessário não tem motivo para precisarmos dele.
Agora vamos olhar o que representa um leilão em si. O leilão tem uma descrição, ou seja, esse leilão é referente a quê? E os lances neste leilão? Um leilão pode receber um lance ou vários lances. Estamos representando aqui como um vector
, que também já aprendemos em treinamentos anteriores, inclusive com templates etc.
A partir disso, vamos dar uma olhada na implementação antes. Temos a inicialização da descrição no construtor e reparamos que o vector
não está sendo inicializado aqui porque o vector
começa vazio mesmo. Não recebemos nada por parâmetro.
Quando colocamos essa linha aqui, na hora que um leilão for criado isso aqui vai criar uma nova instância de um vector
de lances. Isso já vai ter um vector
vazio e vamos ter um leilão sem lances inicialmente. Não precisamos inicializar nada.
Temos aqui umgetter para recuperar os lances. Repare que eu estou devolvendo uma referência constante. Isso quer dizer que eu não estou realizando uma cópia do que vai ser retornado, eu não preciso disso; mas estou retornando constante para que ninguém possa alterar, caso eu receba esse valor. Claro que existem formas de burlarmos isso, mas não vamos entrar nesses detalhes agora.
Um leilão pode receber um lance, recebemos uma referência para um lance aqui e adicionamos esse lance lá no nosso vetor. Essa é a ideia por trás do nosso sistema, é isso que temos até agora. Durante esse treinamento, a ideia é implementarmos funcionalidades novas e em cima dessas funcionalidades realizarmos testes e automatizarmos os possíveis casos de testes.
A partir do próximo vídeo nós vamos começar a implementar funcionalidades novas, organizar melhor as nossas coisas. Enfim, no próximo vídeo começaremos a efetivamente colocar a mão na massa!
Vamos criar agora uma classe que vai realizar a avaliação de um leilão. A princípio essa classe vai avaliar um leilão e nos retornar o maior o lance disponível, o maior lance que foi dado nesse leilão.
Vamos criar aqui uma nova classe. Vou em "New File...", vou criar um arquivo C++, vou adicionar um arquivo de cabeçalho também e vou chamar de Avaliador
. Essa classe de avaliador vai ficar aqui mesmo junto com todos os outros na mesma pasta.
Você provavelmente já percebeu que estou utilizando um sistema diferente dos treinamentos anteriores. Nessa IDE, no Xcode, o modelo que ele cria para nós é diferente. Ao invés de utilizarmos o Pragma para termos o arquivo de cabeçalho, ele utiliza essa forma que é um pouco mais antiga, mas ainda muito comum também.
Vou manter isso para nos habituarmos e vou definir aqui a nossa classe Avaliador
: class Avaliador
. Na definição dessa classe eu preciso ter um método avalia
. Esse método não vai devolver nada, ele vai avaliar um leilão. Obviamente, a minha IDE não conhece esse tipo; se eu salvar aqui, ela vai dar um erro. Eu preciso incluir o cabeçalho de leilão: #include Leilao.hpp
.
Agora eu tenho um método que não devolve nada e avalia um leilão: class Avaliador { public: void avalia(Leilao};
. Quando esse leilão for avaliado, algumas informações serão preenchidas aqui na minha classe.
Algumas informações como o que já comentamos, o maior valor ou o valor mais alto, como você preferir. Vai ser o maior valor de lance que vamos receber nesse leilão: private: float maiorValor;
Basicamente, é isso que precisamos por agora. Vamos para a implementação. Eu vou apagar todos esses comentários. Primeiro, um void Avaliador::avalia(Leilao);
. Talvez você ainda não tenha se habituado com essa ideia, já falamos em treinamentos anteriores. Se você não estiver habituado com a ideia de não colocar o nome da variável aqui, o nome do parâmetro. Isso é perfeitamente válido.
Como aqui o leilão só seria repetido, não faz sentido adicionarmos, não vai adicionar valor nenhum para essa definição. Já na implementação nós precisamos sim de um nome, senão a sintaxe vai ser incorreta.
Vamos continuar! Para avaliar um leilão eu preciso realizar algumas tarefas. Primeiro: pegar o seu maior valor. Para pegar o maior valor eu posso pegar o último valor que foi dado nesse leilão, porque em um leilão alguém coloca um lance e outra pessoa dá um lance maior e outro um lance maior. Eu vou receber o último lance que foi dado nesse leilão.
A primeira coisa que vou fazer vai ser pegar um vetor de lance, que vão ser os lances desse leilão: std::vector<Lance> lances = leilao.recuperaLances();
. Peguei os lances.
Agora eu quero pegar o último lance que vai ser desse vector
temos acesso ao método back
, que vai dar o último elemento deste vetor: Lance ultimoLance = lances.back();
Um detalhe importante é que se esse vetor estiver vazio aqui, o comportamento vai ser indefinido. Pode acontecer outra dependendo do compilador. Não vamos nos preocupar com esse detalhe, pelo menos não por agora.
A partir desse último lance eu vou armazenar lá em maiorValor
o valor desse último lance: maiorValor = ultimoLance.recuperaValor();
. Sem segredo nenhum.
Só que eu armazenei esse maiorValor
e eu preciso de alguma forma disponibilizar ele para alguém pegar. Vamos lá! Eu vou ter um método recuperaMaiorValor
, que vai ser um método const
, ou seja, ele não vai alterar nada na classe: float recuperaMaiorValor() const;
.
Vamos para implementação. Eu vou adicionar o avaliador e colocar a implementação, que vai simplesmente me retornar o maior valor: float Avaliador::recuperaMaiorValor() const { return maiorValor; }
. Segredo nenhum, nada demais.
Aqui temos uma implementação, talvez até ingênua, de um avaliador de leilões. Como garantimos que essa implementação aqui está funcionando? O que podemos fazer para garantirmos que a nossa implementação esteja correta? Precisamos testá-la! Vamos entender como podemos testar um código no próximo vídeo.
O curso C++ e TDD: testes de unidade com Catch2 possui 129 minutos de vídeos, em um total de 56 atividades. Gostou? Conheça nossos outros cursos de C e C++ em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.