Seja bem-vindo(a) a este curso de Python focado em testes e em TDD. Meu nome é Bruno Divino, faço parte do time de instrutores da Alura e vou te acompanhar nessa jornada de aprendizagem. Minha autodescrição: tenho cabelos castanhos, bigode, olhos verde e pele clara. Estou sentado em uma cadeira verde e, ao fundo, há uma parede azul.
Este curso é destinado para pessoas que têm algum conhecimento prévio de Python e que estejam interessadas em desenvolver vários projetos utilizando essa linguagem, sejam eles voltados para Web ou dedicados a outras questões, como automatização e DevOps. A utilização de testes é bem-vinda em várias áreas, trata-se de um assunto bastante generalista e pode ser usado em diversos contextos. Contanto que seja Python, podemos desenvolver bastante com testes.
O único pré-requisito para acompanhar este treinamento é o conhecimento de Python, principalmente direcionado a orientação a objetos. Ao longo do curso, trabalharemos com um projeto que utiliza classes, métodos dentro de classes e instanciação de objetos, por isso, é interessante que você tenha conhecimento prévio relacionado a esse paradigma tão importante da linguagem Python.
No decorrer do curso, ajudaremos a Dominique, uma pessoa desenvolvedora iniciante na empresa Bytebank. O chefe dela a encarregou de desenvolver um projeto e ela tem algumas dúvidas a respeito do que são testes e como eles podem melhorar o processo de desenvolvimento de seus projetos. Então, nos dispomos a ensiná-la sobre o que são e para que servem os testes, bem como de que se trata a metodologia TDD (Test-driven Development). Ao longo desse processo, nós também aprenderemos muito — afinal de contas, a melhor forma de aprender é ensinando.
Agora que sabemos tudo que será abordado neste treinamento, podemos dispensar a ansiedade e relaxar um pouco, pegar um copo de água e nos preparar para começar nossos estudos!
Antes de começarmos o curso, vamos conhecer a história da Dominique.
A Dominique é uma dev iniciante que trabalha na empresa Bytebank, uma fintech (banco digital focado em tecnologia e finanças). Ela está muito empolgada, pois este é seu primeiro emprego como pessoa desenvolvedora. O chefe dela notou seu entusiasmo, então já lhe atribuiu um pequeno projeto que, posteriormente, fará parte de um projeto ainda maior da empresa.
O projeto da Dominique é desenvolver uma classe que contenha as informações dos funcionários do Bytebank. Ela já elaborou o código e, em breve, vamos revisá-lo.
Antes disso, ela pediu nossa ajuda para decifrar alguns termos que sempre encontra no seu dia a dia de trabalho. Ao seu redor, as pessoas devs mais experientes comentam sobre testes, testes unitários e metodologia do TDD e a Dominique nos disse que não sabe exatamente do que se tratam esses termos. Então, além de revisar seus códigos e ajudá-la a avançar em seus projetos, também vamos sanar essas dúvidas e aprender bastante com o que temos a ensinar. Afinal, a melhor forma de aprender é ensinando!
A princípio, vamos analisar o projeto da Dominique. Optei por utilizar o PyCharm como IDE. Para facilitar o acompanhamento do curso, é preferível que você também use, porém não é imprescindível — fica a seu critério.
Abrindo o projeto da Dominique no PyCharm, vamos revisar a estrutura de diretórios, no painel à esquerda. Temos uma pasta chamada codigo
e, dentro dela, há o arquivo bytebank.py
, onde ela criou a classe Funcionario
. Vamos examiná-la, a seguir.
Conforme as regras de negócio passadas pelo chefe dela, a classe Funcionario
deve conter o nome, a data de nascimento e o salário do funcionário. Entre as linhas 9 e 15, notamos que a Dominique já criou um property com nome e outro com salário. Além disso, entre as linhas 17 e 25, há dois métodos que compreendem a regra de negócio da classe (idade
e calcular_bonus
).
O método idade
tem um nome autoexplicativo: ele captura a data de nascimento do funcionário e calcula a idade dele a partir do ano atual. Mais adiante, focaremos no método calcular_bonus
. Nas linhas 27 e 28, temos a função __str__
que retorna as informações completas do objeto.
Antes de testar a classe, vamos acessar o terminal. Notaremos que não existe um ambiente virtual do Python instanciado. Ao desenvolver projetos Python, é interessante termos um ambiente virtual funcionando para não criar conflitos entre diferentes projetos presentes na nossa máquina. Portanto, vamos fazer essa instanciação.
Basta executar o comando python3 -m venv venv
. O primeiro venv
refere-se a virtual environment, o ambiente virtual que estamos criando. O segundo venv
é o nome do ambiente. Podemos escolher outro nome, porém por padrão mantém-se "venv", por isso venv venv
.
Ao pressionar a tecla "Enter", o ambiente virtual será criado e o diretório venv
aparecerá na estrutura de diretórios do projeto, no painel à esquerda. Para ativar o ambiente, rodaremos source 'venv/bin/activate
. A partir de agora, haverá uma tag (venv)
no início da linha no terminal, indicando que estamos nesse ambiente virtual.
Na sequência, podemos testar o código da Dominique. Na pasta codigo
, criaremos um arquivo chamado main.py
e nele chamaremos um objeto para testar a classe Funcionario
. Primeiramente, precisamos importar a classe:
from codigo.bytebank import Funcionario
Depois, criaremos o funcionário lucas
. Seu nome será Lucas Carvalho; a data de nascimento, 2000; e o salário inicial, R$1000,00:
from codigo.bytebank import Funcionario
lucas = Funcionario('Lucas Carvalho', 2000, 1000)
Ao digitar
Funcionario(
, a IDE exibirá uma indicação do próximo argumento que devemos fornecer.
Para visualizarmos o objeto, utilizaremos a função print
:
from codigo.bytebank import Funcionario
lucas = Funcionario('Lucas Carvalho', 2000, 1000)
print(lucas)
Em seguida, para executar o código, clicaremos com o botão direito sobre o código e selecionaremos "Run 'main'". Outra opção é usar o atalho "Ctrl + Shift + F10". Como esperado, teremos no terminal as informações do funcionário Lucas.
Agora, vamos modificar a linha 5 do código, para testar a função idade
:
from codigo.bytebank import Funcionario
lucas = Funcionario('Lucas Carvalho', 2000, 1000)
print(lucas.idade)
Como estamos em 2022, o resultado será 22 — o código está funcionando.
No entanto, se prestarmos atenção, há um ponto estranho na regra de negócio: o funcionário deve informar a data de nascimento (composta por dia, mês e ano) e indicamos somente o ano em que o Lucas nasceu. Vamos alterar a linha 3, designando a data completa e a transformando em uma string:
from codigo.bytebank import Funcionario
lucas = Funcionario('Lucas Carvalho', '13/03/2000', 1000)
print(lucas.idade)
Ao rodar o código novamente, ocorrerá um erro. A regra de negócio está falha, vamos consertá-la no próximo vídeo.
No vídeo passado, encontramos um erro no nosso código, então vamos analisar o arquivo main.py
para entender o que aconteceu.
Estamos utilizando um objeto: o funcionário lucas
que criamos na linha 3, que recebe 'Lucas Carvalho'
como nome, '13/03/2000'
como data de nascimento e 1000
como salário. Depois, na linha 5, chamamos o método idade
para calcular a idade do funcionário.
Inicialmente, ao informar a data de nascimento do Lucas, colocamos apenas o ano. No entanto, notamos que isso seria uma infração à regra de negócio. Quando pensamos em data de nascimento, trata-se de dia, mês e ano — não apenas o ano! Logo, substituímos o ano 2000 por uma string '13/03/2000'
:
from codigo.bytebank import Funcionario
lucas = Funcionario('Lucas Carvalho', '13/03/2000', 1000)
print(lucas.idade)
Porém, essa mudança causou um erro no método idade
. A seguir, vamos verificar o funcionamento dessa função, no arquivo bytebank.py
.
Na linha 18, através da biblioteca date
do Python, recebemos o ano atual (no caso, 2022). Para calcular a idade, na linha 19, a data de nascimento informada pelo funcionário é subtraída do ano atual. Nessa linha, a Dominique usou o método int
para transformar a data de nascimento em um int
, porém se usarmos o formato 13/03/2000, com barras, esse valor não será transformado em int
.
Então, vamos alterar o método idade
para torná-lo funcional novamente. "Quebraremos" a data de nascimento em três partes, formando uma lista com três itens. O primeiro item será o dia; o segundo, o mês; e o terceiro, o ano.
Na linha 18, criaremos uma variável chamada data_nascimento_quebrada
e atribuiremos a ela o resultado de self._data_nascimento.split('/')
:
# código anterior omitido
def idade(self):
data_nascimento_quebrada = self._data_nascimento.split('/')
ano_atual = date.today().year
return ano_atual - int(self._data_nascimento)
# código posterior omitido
No vídeo, há um pequeno erro de digitação na variável
data_nascimento_quebrada
, mas ele já foi corrigido nas transcrições.
O split
é um método do Python utilizado para formatar strings. Com ele, vamos "quebrar" a string em determinados pontos e retornar uma lista com essas partes "quebradas". Dentro do split
, passaremos o caractere usado como referência para realizar essas quebras. No nosso caso, é a barra (/
). Assim, teremos uma lista com três itens: dia, mês e ano.
Em seguida, vamos criar uma variável chamada ano_nascimento
e igualá-la ao último item da lista data_nascimento_quebrada
. Usaremos data_nascimento_quebrada[-1]
para selecionar o último item da lista:
# código anterior omitido
def idade(self):
data_nascimento_quebrada = self._data_nascimento.split('/')
ano_nascimento = data_nascimento_quebrada[-1]
ano_atual = date.today().year
return ano_atual - int(self._data_nascimento)
# código posterior omitido
Por fim, na linha 21, substituiremos self._data_nascimento
por ano_nascimento
:
# código anterior omitido
def idade(self):
data_nascimento_quebrada = self._data_nascimento.split('/')
ano_nascimento = data_nascimento_quebrada[-1]
ano_atual = date.today().year
return ano_atual - int(ano_nascimento)
# código posterior omitido
Na sequência, vamos executar o código de main.py
. Basta abrir o arquivo, clicar com botão direito do mouse sobre ele e selecionar "Run 'main'" (ou usar o atalho "Ctrl + Shift + F10"). O retorno será a idade de Lucas, 22 anos. Ou seja, após as alterações, o código voltou a funcionar.
Assim, nós instanciamos lucas
como um funcionário e exibimos sua idade no terminal, porém o chefe da Dominique gostaria que transformássemos esse processo em um teste automatizado. Então, vamos comentar as linhas 3 e 5, e desenvolver esses testes.
A partir da linha 7, criaremos um método chamado teste_idade
, em que instanciaremos um novo funcionário. O nome dele será 'Teste'
, a data de nascimento será '13/03/2000'
e o salário, 1111
:
from codigo.bytebank import Funcionario
#lucas = Funcionario('Lucas Carvalho', '13/03/2000', 1000)
#print(lucas.idade)
def teste_idade():
funcionario_teste = Funcionario('Teste', '13/03/2000', 1111)
Em seguida, usando o prefixo f
, vamos printar o valor formatado:
# código anterior omitido
def teste_idade():
funcionario_teste = Funcionario('Teste', '13/03/2000', 1111)
print(f'Teste = {funcionario_teste.idade()}')
Acabamos de criar um teste automatizado. Informamos alguns valores e o teste indicará se tudo está funcionando como esperado. Antes de rodar o código, precisamos chamar teste_idade
:
# código anterior omitido
def teste_idade():
funcionario_teste = Funcionario('Teste', '13/03/2000', 1111)
print(f'Teste = {funcionario_teste.idade()}')
teste_idade()
Por fim, vamos executar o código. O retorno estará correto! Sendo assim, o nosso primeiro teste automatizado está pronto. Vale notar que ele está dentro de um método, onde poderíamos aplicar várias outras lógicas mirabolantes para testar o código da Dominique.
Visto que tudo está funcionando corretamente, podemos remover as linhas comentadas do arquivo para deixá-lo mais enxuto:
from codigo.bytebank import Funcionario
def teste_idade():
funcionario_teste = Funcionario('Teste', '13/03/2000', 1111)
print(f'Teste = {funcionario_teste.idade()}')
Então, falamos bastante sobre testes e criamos um teste automatizado, mas o que são testes automatizados, afinal? Se há testes automatizados, quer dizer que existem testes não automatizados? Quais tipos de testes existem? Vamos explorar essas questões na próxima aula.
O curso Python e TDD: explorando testes unitários possui 150 minutos de vídeos, em um total de 47 atividades. Gostou? Conheça nossos outros cursos de Python 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:
Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com Luri até 100 mensagens por semana.
Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.
Acesso completo
durante 1 ano
Estude 24h/dia
onde e quando quiser
Novos cursos
todas as semanas