Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Testes unitários como ferramentas de design de código

189 views

Published on

Apresentação para o I GruPy Grande Rio

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Testes unitários como ferramentas de design de código

  1. 1. Testes unitários como ferramentas de design de código I GruPy Grande Rio - 2 de abril de 2016
  2. 2. Paula Grangeiro Programadora por profissão, desenhista nas horas vagas e colecionadora de gatos.
  3. 3. Sobre mim
  4. 4. Ministério da procrastinação adverte: Os fatos relatados durante esta apresentação são baseados em experiências pessoais. Utilize-os com moderação.
  5. 5. Por que pensar em Design de Código?
  6. 6. Código Mogwai
  7. 7. “Escrever código limpo é o que você deve fazer para que possa se intitular como profissional. Não existem desculpas plausíveis para fazer menos do que o seu melhor.” - Uncle Bob em Código Limpo
  8. 8. Testes unitários
  9. 9. def foo(arg): if arg: return ‘It has an argument!’ return ‘Nope!’ Pequena função Python com dois possíveis fluxos a partir da validação do argumento
  10. 10. Testes unitários que cobrem os possíveis fluxos da função foo class FooTestCase(TestCase): def test_foo_returns_correct_value_when_arg_is_true(self): message = foo(True) self.assertEqual(‘It has an argument!’, message) def test_foo_returns_correct_value_when_arg_is_false(self): message = foo(False) self.assertEqual(‘Nope!’, message)
  11. 11. class FooTestCase(TestCase): def test_foo_returns_correct_value_when_arg_is_true(self): message = foo(True) self.assertEqual(‘It has an argument!’, message) def test_foo_returns_correct_value_when_arg_is_false(self): message = foo(False) self.assertEqual(‘Nope!’, message) def foo(arg): if arg: return ‘It has an argument!’ return ‘Nope!’
  12. 12. Então o que há de errado com o nosso código?
  13. 13. Padrões de Projeto Design Patterns
  14. 14. Padrões de Projeto ● GoF ● GRASP ● SOLID
  15. 15. Indicação de estudo ● Padrões de Projeto - Soluções Reutilizáveis de Software Orientado a Objetos ● Utilizando UML e Padrões ● Código limpo ● Curso Python Patterns - Luciano Ramalho
  16. 16. Testes unitários como ferramenta de design
  17. 17. class CrateIncomeTaxTestCase(TestCase): def test_method_calcs_exemption_corrctly (self): ``` teste para rendimento < 25661.7 ``` def test_method_calcs_taxes_correctly(self): ``` teste para rendimento > 25661.7 ``` def test_method_creates_file_correctly(self): ``` teste que valida criacao do arquivo ``` Teste unitariamente o seu código def create_income_tax(income): tax = 0 if income < 25661.7: ``` codigo calculo do imposto isento ``` else: ``` codigo calculo do imposto ``` f = open('income_tax_file', 'w') f.write(tax) f.close()
  18. 18. class CreateIncomeTaxTestCase(TestCase): def test_method_calls_calculate_tax(self): ``` teste para chamada do calcular imposto ``` def test_method_calls_create_file(self): ``` teste para chamada do criar arquivo ``` class CalculateTaxTestCase(TestCase): def test_method_calcs_exemption_correctly (self): ``` teste para rendimento < 25661.7 ``` def test_method_calcs_taxes_correctly(self): ``` teste para rendimento >= 25661.7 ``` class CreateFileTestCase(TestCase): def test_method_creates_file_correctly(self): ``` teste que valida criacao do arquivo ``` Teste unitariamente o seu código def create_income_tax(rendimento): tax = calculate_tax(rendimento) income_tax_file = create_file(valor_imposto)
  19. 19. class PatientTestCase(TestCase): def test_save_patient_correctly(self): ``` codigo que testa se o paciente foi salvo corretamente ``` def test_save_raises_exception_if_patient_with_same_cpf_already_exists(self): ``` codigo que testa se foi levantada excecao quando paciente com cpf ja existe ``` patient_1 = Patient(cpf=’12121212108’) patient_1.save() patient_2 = Patient(cpf=’12121212108’) self.assertRaises(PatientAlreadyExistsException, patient_2.save) Teste fluxos de sucesso e erro separadamente
  20. 20. class CalculateTaxTestCase(TestCase): def test_method_calcs_taxes_when_income_less_than_margin(self): expected_value = 0 income = 25000 taxes = calculate_tax(income) self.assertEqual(expected_value, taxes) def test_method_calcs_taxes_when_income_equal_or_greater_than_margin(self): expected_value = 432.6 income = 26000 taxes = calculate_tax(income) self.assertEqual(expected_value, taxes) Nomeie os testes de acordo com o fluxo testado
  21. 21. from mock import patch from unittest import TestCase from diretorio.arquivo import create_income_tax class CreateIncomeTaxTestCase(TestCase): @patch(‘diretorio.arquivo.calculate_tax’) def test_method_calls_calculate_tax(self, mocked_calculate_tax): create_income_tax(1) self.assertTrue(mocked_calculate_tax.called) @patch(‘diretorio.arquivo.create_file’) def test_method_calls_create_file(self, mocked_create_file): create_income_tax(1) self.assertTrue(mocked_create_file.called) Testes devem ser isolados!
  22. 22. TDD
  23. 23. Funcionamento do Dojo
  24. 24. ● DTM todas as quartas ● Colworking todas as segundas ● dojo-rio@googlegroups.com Dojos no Rio
  25. 25. http://www.paulagrangeiro.com.br https://twitter.com/paulagrangeiro http://fb.me/paula.grangeiro https://github.com/pgrangeiro pgrangeiro.dev@gmail.com Obrigada!

×