UNITTEST
Felipe Ruhland
@ Ecentry
Python unittest framework
KENT BECK
SIMPLE SMALTALK TESTING: with patterns
COOKBOOK
PHILOSOPHY
FAILURES and ERRORS
UNIT TESTING
INTEGRATION TESTING
RUNNING TESTS
COOKBOOK
PHILOSOPHY
FIXTURE
Subclass TestCase
Subclass TestCase
Add an instance variable for each known
object in the fixture
Subclass TestCase
Add an instance variable for each known
object in the fixture
Override setUp to initialize the variables
TEST CASE
CHECK
PYTHON UNITTEST
SOME IMPORTANT CONCEPTS
TEST FIXTURE
TEST FIXTURE
TEST CASE
TEST FIXTURE
TEST CASE
TEST SUITE
TEST FIXTURE
TEST CASE
TEST SUITE
TEST RUNNER
unittest.TestCase(methodName='runTest')
FIRST GROUP
FIRST GROUP
setUp()
FIRST GROUP
setUp()
tearDown()
FIRST GROUP
setUp()
tearDown()
setUpClass()
FIRST GROUP
setUp()
tearDown()
setUpClass()
tearDownClass()
FIRST GROUP
setUp()
tearDown()
setUpClass()
tearDownClass()
run(result=None)
github.com/feliperuhland
feliperuhland.com
@feliperuhland
THANK YOU

Editor's Notes

  • #3 O primeiro paragrafo da documentação do Python já descreve a origem do framework de unittest. O framework de teste unitário pra Python, também conhecido como PyUnit, é uma versão em Python do JUnit, que por sua vez é a versão do Java para o framework de teste para SmallTalk definido pelo Bent Beck.
  • #4 Criador do Extreme Programming e um dos responsáveis pelo Manifesto Ágil. Um dos líderes do TDD e autor do framework para testes unitários para smaltalk, que foi o “pai” de todos os frameworks de testes unitários (JUnit e etc). Hoje trabalha no Facebook.
  • #5 A documentação do framework (que tem distribuição livre, claro) é dividida em três partes: Filosofia, Livro de Receitas e o Framework em si.
  • #6 Na parte da filosofia, ele relata que não é nada fã de testes baseados em interface gráfica, pois é comum que pequenas mudanças cosméticas acabam quebrando diversos testes da noite pro dia, pois a saída esperada não era mais a mesma. A equipe perdia mais tempo ajustando os testes do que implementando novas funcionalidades. A solução encontrada foi escrever os testes e verificar o resultado com SmallTalk. Ele ressalta que uma desvantagem era que os testers precisariam elaborar os testes com o smalltalk, mas que os resultados eram muito mais satisfatórios.
  • #7 O framework faz distinção entre esses dois resultados negativos. A falha é a antecipação de um problema. Quer dizer que o resultado obtido não é igual ao esperado. O erro é um problema bem mais complicado, pois não foi possível nem verificar o resultado obtido.
  • #8 Ele recomenda que os desenvolvedores escrevam seus próprios testes unitários e que, de preferência, gastem de 25%-50% do seu tempo com eles. Também recomenda que os testes sejam organizados por Suites de Teste, que tenham testes de classes, que tenham testes unitários.
  • #9 Nesta etapa, ele recomenda que um outro desenvolvedor/tester faça os testes. Mas como estes testes devem ser feitos? Ele diz que só existe uma resposta: usar a interface do usuário, mas fazer isso com testes.
  • #10 Para encerrar a parte de filosofia, ele destaca que é tentador elaborar vários testes, rodá-los e depois limpar o ambiente. Ele diz que não é bem assim e que na maioria das vezes isso traz mais problemas do que soluções, pois os testes acabam interfarindo um no outro e uma falha pode impedir que outros testes sejam executados. No framework, os dados são criados e removidos a cada teste. Isso pode causar um problema de performance, mas facilita pois os testes podem rodar sem observação.
  • #11 No livro de receitas, ele destaca os padrões que devem ser utilizados.
  • #12 Como se deve começar a elaboração de testes? Ele argumenta que testes são umas das atividades mais impossíveis de serem feitas. Que tu tentas fazer de forma mais completa, para garantir o funcionamento do teu software, mas, em muitos casos, são tantas variáveis envolvidas que fica - literalmente - impossível de cobrir todas as combinações. Ele relata que se tu não souberes exatamente o que tais testando, é provável que tu nunca consigas terminar o teste e comenta que se deve começar por um caminho mais simples e previsível, para ir aumentando a complexidade, conforme for conhecendo mais as configurações. Estas configurações são chamadas de FIXTURE. Ao definir as fixtures, o desenvolvedor escolhe o que vai ser testado e o que não vai. Por onde começar?
  • #16 Depois da fixture, o que vem depois? Para criar um teste unitário, é necessário prever a situação de alguma forma. Deve-se criar um método na classe e “estimular” a fixture neste método. Tá, beleza. Muitos estímulos. E agora?
  • #17 Um TestCase estimula a fixture, mas como comparar o resultado? Se for testes de interação com usuário, deve ser observados os resultados diretamente. Se for um teste que tem um retorno, a comparação deve ser feita diretamente com o valor retornado.
  • #18 Agora mais específico do Unittest do Python.
  • #19 Alguns conceitos importantes:
  • #20 Representa a preparação necessária para rodar um (ou mais) testes e limpar qualquer rastro deixado pelo testes. Exemplos: criar arquivos temporários, proxys, banco de dados, diretórios e etc.
  • #21 O testcase é a menor parte de um teste unitário. Ele deve ter um objetivo específico. O unittest disponibiliza uma case para ser extendida; TestCase para criar novos testcases.
  • #22 A suite de teste é uma coleção de test cases que rodam juntos.
  • #23 O test runner é o componente que orquestra a execução dos testes e promove o output para o usuário.
  • #24 É a classe base para ser extendida em nossos testes. Ela possue a interface necessária para o runner executar os testes. O TestCase disponibiliza três grupos de métodos. Um grupo é usado para rodar os testes, outro é usado para verificar as condições e relatórios de falhas e outro com informações do próprio teste.
  • #26 setUp() é o método chamado para preparar a fixture de teste. Ele é chamado imediatamente antes do método do teste. Se uma exceção for lançada nesse método, o teste será considerado como erro. A implementação padrão não faz nada.
  • #27 tearDown() É o método chamado imediatamente após o método de teste. Este método é executado mesmo de o test lançou uma exceção, por isso deve ter cuidado com a implementação do estado interno. Se uma exceção for lançada no método, será considerado erro. Ele somente será executado se o setUp() for rodado com sucesso. A implementação padrão não faz nada.
  • #28 setUpClass() É um método da classe que é chamada antes dos testes de uma classe rodarem. Deve conter o decorator classmethod():
  • #29 tearDownClass() É um metodo de classe que roda após os testes de uma classe. E precisa ser decorado com classmethod()
  • #30 run(result=None) Método responsável por executar o teste, coletar o resultado e definir um objeto com o resultado. Detalhe que ele não retorna o objeto.