Slide 1

Slide 1 text

TDD, Testes e Design! Maurício Aniche

Slide 2

Slide 2 text

TDD • Já sabemos que: • Vermelho -> Verde -> Refatora • “TDD é sobre design, não sobre teste” • “Se seu código é difícil testar, é pq o design precisa mudar” • O que mais tem pra falar?

Slide 3

Slide 3 text

TDD, Testes e Design! Escrever testes vs testar! Maurício Aniche

Slide 4

Slide 4 text

Maurício F. Aniche Assistant Professor @ TU Delft M.FinavaroAniche@tudelft.nl mauricioaniche.com

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Escrever testes vs testar https://sttp.site/chapters/getting-started/testing-vs-writing-tests.html

Slide 7

Slide 7 text

Guiar o desenvolvimento vs achar bug https://sttp.site/chapters/getting-started/testing-vs-writing-tests.html

Slide 8

Slide 8 text

Escrever testes vs testar • Ritmo de trabalho • Reflete sobre o código e design • Refatoração como parte do ciclo • Geração de modelos pra suportar o teste • Análise do domínio • Análise do limite (boundary) • Teste estrutural como complemento • Teste inteligente (AI, análise estática, mutante)

Slide 9

Slide 9 text

Escrever testes vs testar • Ritmo de trabalho • Reflete sobre o código e design • Refatoração como parte do ciclo • Geração de modelos pra suportar o teste • Análise do domínio • Análise do limite (boundary) • Teste estrutural como complemento • Teste inteligente (AI, análise estática, mutante, fuzzing) Todo mundo fala sobre na comunidade! Poucos falam sobre na comunidade!

Slide 10

Slide 10 text

“Corretude by design” não é suficiente!

Slide 11

Slide 11 text

Modelos! • Não descarte a possibilidade de criar modelos que te ajudarão no teste. • Modelos abstraem a complexidade do sistema, e te ajudam a ver o que importa. • (“Ah, mas agile fala pra não fazer documentação… Meus amigos vão me chamar de Waterfallzeiro se eu committar algo que não é código!) • Claro que só onde faz sentido!

Slide 12

Slide 12 text

Passive learning Modelar o comportamento do sistema a partir de observações do sistema real. 20170101160001 Adyen version: ****** 20170101160002 Starting TX/amt=10001/currency=978 20170101160003 Starting EMV 20170101160004 EMV started 20170101160005 Magswipe opened 20170101160006 CTLS started 20170101160007 Transaction initialised 20170101160008 Run TX as EMV transaction 20170101160009 Application selected app:****** 20170101160010 read_application_data succeeded 20170101160011 data_authentication succeeded 20170101160012 validate 0 20170101160013 DCC rejected 20170101160014 terminal_risk_management succeeded 20170101160015 verify_card_holder succeeded 20170101160016 generate_first_ac succeeded 20170101160017 Authorizing online 20170101160018 Data returned by the host succeeded 20170101160019 Transaction authorized by card 20170101160020 Approved receipt printed 20170101160021 pos_result_code:APPROVED 20170101160022 Final status: Approved 20170101160001 Adyen version: ****** 20170101160002 Starting TX/amt=10001/currency=978 20170101160003 Starting EMV 20170101160004 EMV started 20170101160005 Magswipe opened 20170101160006 CTLS started 20170101160007 Transaction initialised 20170101160008 Run TX as EMV transaction 20170101160009 Application selected app:****** 20170101160010 read_application_data succeeded 20170101160011 data_authentication succeeded 20170101160012 validate 0 20170101160013 DCC rejected 20170101160014 terminal_risk_management succeeded 20170101160015 verify_card_holder succeeded 20170101160016 generate_first_ac succeeded 20170101160017 Authorizing online 20170101160018 Data returned by the host succeeded 20170101160019 Transaction authorized by card 20170101160020 Approved receipt printed 20170101160021 pos_result_code:APPROVED 20170101160022 Final status: Approved 20170101160001 Adyen version: ****** 20170101160002 Starting TX/amt=10001/currency=978 20170101160003 Starting EMV 20170101160004 EMV started 20170101160005 Magswipe opened 20170101160006 CTLS started 20170101160007 Transaction initialised 20170101160008 Run TX as EMV transaction 20170101160009 Application selected app:****** 20170101160010 read_application_data succeeded 20170101160011 data_authentication succeeded 20170101160012 validate 0 20170101160013 DCC rejected 20170101160014 terminal_risk_management succeeded 20170101160015 verify_card_holder succeeded 20170101160016 generate_first_ac succeeded 20170101160017 Authorizing online 20170101160018 Data returned by the host succeeded 20170101160019 Transaction authorized by card 20170101160020 Approved receipt printed 20170101160021 pos_result_code:APPROVED 20170101160022 Final status: Approved 20170101160001 Adyen version: ****** 20170101160002 Starting TX/amt=10001/currency=978 20170101160003 Starting EMV 20170101160004 EMV started 20170101160005 Magswipe opened 20170101160006 CTLS started 20170101160007 Transaction initialised 20170101160008 Run TX as EMV transaction 20170101160009 Application selected app:****** 20170101160010 read_application_data succeeded 20170101160011 data_authentication succeeded 20170101160012 validate 0 20170101160013 DCC rejected 20170101160014 terminal_risk_management succeeded 20170101160015 verify_card_holder succeeded 20170101160016 generate_first_ac succeeded 20170101160017 Authorizing online 20170101160018 Data returned by the host succeeded 20170101160019 Transaction authorized by card 20170101160020 Approved receipt printed 20170101160021 pos_result_code:APPROVED 20170101160022 Final status: Approved 20170101160001 Adyen version: ****** 20170101160002 Starting TX/amt=10001/currency=978 20170101160003 Starting EMV 20170101160004 EMV started 20170101160005 Magswipe opened 20170101160006 CTLS started 20170101160007 Transaction initialised 20170101160008 Run TX as EMV transaction 20170101160009 Application selected app:****** 20170101160010 read_application_data succeeded 20170101160011 data_authentication succeeded 20170101160012 validate 0 20170101160013 DCC rejected 20170101160014 terminal_risk_management succeeded 20170101160015 verify_card_holder succeeded 20170101160016 generate_first_ac succeeded 20170101160017 Authorizing online 20170101160018 Data returned by the host succeeded 20170101160019 Transaction authorized by card 20170101160020 Approved receipt printed 20170101160021 pos_result_code:APPROVED 20170101160022 Final status: Approved Rick Wieman, Maurício Aniche, Willem Lobbezoo, Sicco Verwer and Arie van Deursen. An Experience Report on Applying Passive Learning in a Large-Scale Payment Company. ICSME Industry Track, 2017

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

O dobro de erros!

Slide 15

Slide 15 text

Timeout

Slide 16

Slide 16 text

Page Objects

Slide 17

Slide 17 text

Signup Error Login Error Registering About Authenticating not-ok not-ok close close ok Authenticated ok logoff about signup login Public

Slide 18

Slide 18 text

Análise do domínio e limites • Estudos empíricos mostram que um grande número de bugs acontecem nas “fronteiras” do domínio. • Teste os limites! • Tem um if(x > 10), testa o que acontece entre 9, 10, 11. • Tem um for? Testa 0, 1, N. • Analisar variável por variável por ajudar. • Você pensa em todas fronteiras quando faz TDD? • Eu não! L https://sttp.site/chapters/testing-techniques/domain-testing.html

Slide 19

Slide 19 text

Teste estrutural • (“Ah, code coverage não serve pra nada, é fácil de enganar, patati patató”) • Code coverage não é sobre um número. • É sobre aumentar a sua suíte de testes (que você criou baseado no que sabe do requisito) baseado no que você vê no código. • A ferramenta de cobertura pode te ajudar a encontrar códigos que não são explícitos no requisito. https://sttp.site/chapters/testing-techniques/structural-testing.html

Slide 20

Slide 20 text

https://github.com/apache/commons- lang/tree/e0b474c0d015f89a52c4cf8866fa157dd89e7d1c/src/main/java/org/apach e/commons/lang3/StringUtils.java#L1564

Slide 21

Slide 21 text

Retorna mesma instância do objeto, se não deletou nada… Não tá na spec, mas tá no código!

Slide 22

Slide 22 text

Dublês e mocks • Facilitam demais o teste. • Em especial quando dependências são difíceis ou caras de serem simuladas. • Escolha o tipo de dublê certo: • Fake: uma implementação simplística • Stubs: retorna valores hard-coded • Mocks: grava as interações com o objeto, pq depois você vai perguntar se elas aconteceram! • Decidir ou não se mockar é uma boa ideia! https://sttp.site/chapters/pragmatic-testing/test-doubles.html

Slide 23

Slide 23 text

State testing vs interaction testing • Duas escolas diferentes de TDD. • Classical vs London • State vs Interaction testing • State testing: eu testo a “mudança de estado” do meu objeto. • Invoco método A.a(), não ligo pra como A.a() faz o trabalho, ou de quem ele depende, faço a asserção para garantir que A tem um novo estado. • Interaction testing: eu testo “interação” entre dependências • Invoco método A.a(). A depende de uma abstração B. Eu garanto que A invoca B da maneira correta. • Pensa nos seus Mockito.verify(). Você está garantindo a integração.

Slide 24

Slide 24 text

To mock or not mock? • “Se você usa mock, você tá testando o mock!” • Problema: • SuperServico depende de RepositorioDeNotasFiscais#pegaTodasDoMes(). • pegaTodasDoMes() nunca retorna nulo. • Quando testa SuperServico, desenvolvedor mocka pegaTodasDoMes() • Testes passam • No futuro, desenvolvedor 2 faz pegaTodasDoMes() retornar nulo. • Testes passam, mas em produção quebra. • O problema é manter o mock com o mesmo contrato da classe original. • Difícil mockar se design é inconstante. Requer times com bons designers!

Slide 25

Slide 25 text

Design-by-contracts • Pense de maneira rigorosa sobre o contrato que seus métodos e serviços oferecem pro mundo de fora. • Pré-condições, pós-condições, invariantes. • Deixe-as explícitas no código! • Mudou alguma delas? Análise em cascata! • Hyrum’s law: “Dado um número suficiente de clientes, não importa o que você promete no contrato. Todo e qualquer comportamento observado no sistema será dependido por alguém”. https://www.hyrumslaw.com https://sttp.site/chapters/testing-techniques/design-by-contracts.html

Slide 26

Slide 26 text

Teste inteligente • Até então, você desenhou os todos. A máquina só executou! • Pq não deixar a máquina criar uns testes pra você também? • Não, não é ficção! • Não, AI não vai dominar o mundo! • Pense em: • Análise estática • Testes de mutantes • Fuzz testing • Geração automática de casos de testes https://sttp.site/chapters/intelligent-testing/

Slide 27

Slide 27 text

Análise estática • Desde linters simples até análises mais complicadas. • Veja Facebook’s Infer • Veja Google’s errorprone • Veja Uber’s NullAway https://sttp.site/chapters/intelligent-testing/static-testing.html

Slide 28

Slide 28 text

Testes de mutante • Uma suíte de testes forte é aquela que te revela bugs, quando bugs acontecem. • Mutante: uma pequena variação (bugada) do seu código. Seu teste falha? • Imagina um “if(x>10)”. Se eu trocasse por “if(x>=10)”, algum teste falharia? • Sim? Ótimo. Não? Talvez valha a pena reforçar a sua suíte de teste. • Hipótese: • código é escrito por um programador “competente” e erros acontecem por combinações de erros simples. • “Falhas complicadas” acontecem por causa de “falhas simples”. https://sttp.site/chapters/intelligent-testing/mutation-testing.html

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Geração automática de teste • Se você parar pra pensar, um caso de teste é: • Cria a classe, pelo construtor. • Invoca um método. • Passa valores pra esse método • Faz a asserção no final. • A máquina pode criar código como esse! https://sttp.site/chapters/intelligent-testing/sbst.html

Slide 31

Slide 31 text

Problema do oráculo • Como saber o que um programa tem que produzir? • Difícil… • Mas sabemos de muitas coisas, independente do programa. • Ele não pode soltar exceção. • A app mobile não pode congelar. • Ele não pode demorar mais que X segundos. • Até contextual: Ele não pode retornar nota fiscal com valor negativa… • Esse tipo de bug, a máquina pode facilmente procurar pra você!

Slide 32

Slide 32 text

Ferramentas estão aí (mas ainda não maduras)! • Randoop: gera aleatório! • EvoSuite: usa algoritmo genético pra achar uma boa suíte de testes!

Slide 33

Slide 33 text

Botsing, EvoSQL, EvoMaster, and others!

Slide 34

Slide 34 text

Grandes empresas já pensam nisso!

Slide 35

Slide 35 text

https://sttp.site/chapters/getting-started/developer-testing-workflow.html

Slide 36

Slide 36 text

Não falei de… • Design de código de teste • Invista em infraestrutura de testes • Leia sobre design patterns e code smells em códigos de teste • Property-based testing • Boa ideia, em especial quando combinado com DbC • (Eu tenho pouca experiência prática…) • Design for testability • Boas práticas de arquitetura para facilitar testes. • Fundamental!! • Decidir nível do teste • Sinto que todo mundo já tem um bom feeling de quando usar teste de unidade ou teste de sistema

Slide 37

Slide 37 text

https://sttp.site

Slide 38

Slide 38 text

Obrigado!