Testing Sucks Leo Balter - BrazilJS 2012                              JS
Testar é chato!
Testes vs Testar!
Testes humanos         • Repetitivos         • Estressantes         • Cansativos
Concentração    polarizada• Nos concentramos em um único ponto• Não vemos os demais• falsa sensação de segurança
OlharViciado
Testes de Trollagem
Pare de “ficar testando”      seu código
JSHint/JSLint não testa           código!• Convenção de estilo• Erros comuns• “As Boas Partes”
Mito doCompilador
Pânico vs Benefícios• Muito fácil criar testes para algo que ainda  não existe• Não tão simples quando a aplicação já  exi...
Aplicaçãonão testada
A Síndrome do   “o que estáfuncionando nãose deve mexer”.
Quebre a aplicação!• Criamos testes simples que passem• Teste o que está em produção• Cobertura de testes• O que é crítico...
Acredite:Sua aplicação vai falhar!
Já viu essa síndrome?• Não vai ao médico pra evitar descobrir um  mal grave• Pode haver um problema latente que vai  falha...
Na aplicação• Não testamos para não descobrir o que  falha• Há problemas latentes que vão falhar em  momentos críticos (Po...
Estabeleça o que é         crítico• Quão crítico é cada parte do seu sistema?• Se não funcionar, quais as consequências?
Alto                               Ri                                   sc                                      o         ...
Automatização• --Retrabalho• --Surpresas• Mais tempo para o que é interessante• Menos tempo para testar tudo novamente
Automatização• --Retrabalho• --Surpresas• Mais tempo para o que é interessante• Menos tempo para testar tudo novamente
Metodologias Ágeis• Aplicar testes é uma rotina contida em  Metodologias Ágeis• Testes não dependem de metodologias ágeis•...
FuncionaFaz o que deveria
Esse código funciona!            • Um código pode              funcionar              perfeitamente            • Estar 100...
Fluxo
EspecificaçãoFluxo
Especificação                Plano de TestesFluxo
Especificação                Plano de TestesFluxo                             Testes
Validação
ValidaçãoPlano de Testes
ValidaçãoPlano de Testes Especificação
ValidaçãoPlano de Testes   Testes Especificação
ValidaçãoPlano de Testes    Testes Especificação     Aplicação
Testes não validam  especificação!Testes não criam especificação!
Testes vs Especificação• Se os testes validassem especificação, não  poderiamos prever correções de bugs e  comportamentos d...
Teste que Falha        Código          Refatorar             Baby Steps                  (Testes Unitários)
Sempre em Baby Steps• Ótimo para pegar o ritmo• função 1, 2, 3, pin• Treino do Lutador
Cobertura   de Código
function foo( bar ) {  if ( bar ) {    console.log( yes! );  else {    console.log( no! );  }}
function foo( bar ) {  if ( bar ) {    console.log( yes! );  else {    console.log( no! );  }}
function foo( bar ) {  if ( bar ) {    console.log( yes! );  else {    console.log( no! );  }}
function foo( bar ) {  if ( bar ) {    console.log( yes! );  else {    console.log( no! );  }}
function foo( bar ) {  if ( bar ) {    console.log( yes! );  else {    console.log( no! );  }}
function foo( bar ) {  if ( bar ) {    console.log( yes! );  else {    console.log( no! );  }}
Código 100% coberto     por testes!
• JSCoverage• CoverJS
Tudo é testável• Complexidade vs Criticidade• window.location.replace()
JSTestes em JavaScript
Testes            UnitáriosInterface           FuncionaisDesempenho         Integração
Open Webvários ambientes
FirefoxChrome                        Opera         IE 8, 9[, 10, ...]
FirefoxChrome       Mobile           Opera         IE 8, 9[, 10, ...]
PhantomJS       Webkit
Ferramentas QUnit     NodeUnitMocha    Vows   Jasmine
Estilos de TestesTDD   BDD   Exports
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );});          http://qunitjs.com/
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
BDDdescribe("A suite", function() {  it("spec with an expectation",      function(){       expect(true).toBe(true);      }...
BDDdescribe("A suite", function() {  it("spec with an expectation",      function(){       expect(true).toBe(true);      }...
BDDdescribe("A suite", function() {  it("spec with an expectation",      function(){       expect(true).toBe(true);      }...
BDDdescribe("A suite", function() {  it("spec with an expectation",      function(){       expect(true).toBe(true);      }...
BDDdescribe("A suite", function() {  it("spec with an expectation",      function(){       expect(true).toBe(true);      }...
BDDdescribe("A suite", function() {  it("spec with an expectation",      function(){       expect(true).toBe(true);      }...
Exportsmodule.exports = {     test1: function (test) {         test.equals(this.foo, bar);         test.done();     }};
Exportsmodule.exports = {     test1: function (test) {         test.equals(this.foo, bar);         test.done();     }};
Exportsmodule.exports = {     test1: function (test) {         test.equals(this.foo, bar);         test.done();     }};
Exportsmodule.exports = {     test1: function (test) {         test.equals(this.foo, bar);         test.done();     }};
Exportsmodule.exports = {     test1: function (test) {         test.equals(this.foo, bar);         test.done();     }};
Comocomeçar?
HTML Estático  JavaScript    Testes
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.c...
Código testado tem  bom desempenho?• Testes unitários não medem desempenho• Existem testes de desempenho• Código sem erros...
DexterJS
Dexter.spy
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
test( carly(), 4, function() {      var spy = Dexter.spy( window, carly, function( arg1 ) {            equal( arg1, crazy!...
Dexter.stub
function carly( crazy ) {  if ( typeof ( crazy ) === number ) {    return Call me maybe?;  } else {    return Hey, I just ...
test( stubbed carly(), 1, function() {  var stub = Dexter.stub( window, carly, function() {    return relax;  });  equal( ...
test( stubbed carly(), 1, function() {  var stub = Dexter.stub( window, carly, function() {    return relax;  });  equal( ...
test( stubbed carly(), 1, function() {  var stub = Dexter.stub( window, carly, function() {    return relax;  });  equal( ...
test( stubbed carly(), 1, function() {  var stub = Dexter.stub( window, carly, function() {    return relax;  });  equal( ...
test( stubbed carly(), 1, function() {  var stub = Dexter.stub( window, carly, function() {    return relax;  });  equal( ...
test( stubbed carly(), 1, function() {  var stub = Dexter.stub( window, carly, function() {    return relax;  });  equal( ...
test( stubbed carly(), 1, function() {  var stub = Dexter.stub( window, carly, function() {    return relax;  });  equal( ...
Dexter.fakeXHR
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
test( a fakeXHR, 2, function() {      var fakeXHR = Dexter.fakeXHR();      $.get( /ajax.url, function() {            ok( t...
Começar a criar testes?
Experimente!
Referências• Coding Dojo• Inicialize um projeto com o GruntJS• TDD - Kent Back• Engenharia de Software - Roger S Pressman•...
Obrigado!            @leobalter        leo@balter.com.br                                         JShttp://search.cpan.org/...
Testing sucks
Testing sucks
Testing sucks
Testing sucks
Upcoming SlideShare
Loading in …5
×

Testing sucks

1,261 views

Published on

Presentation given in BrazilJS 2012

Published in: Technology, Business

Testing sucks

  1. 1. Testing Sucks Leo Balter - BrazilJS 2012 JS
  2. 2. Testar é chato!
  3. 3. Testes vs Testar!
  4. 4. Testes humanos • Repetitivos • Estressantes • Cansativos
  5. 5. Concentração polarizada• Nos concentramos em um único ponto• Não vemos os demais• falsa sensação de segurança
  6. 6. OlharViciado
  7. 7. Testes de Trollagem
  8. 8. Pare de “ficar testando” seu código
  9. 9. JSHint/JSLint não testa código!• Convenção de estilo• Erros comuns• “As Boas Partes”
  10. 10. Mito doCompilador
  11. 11. Pânico vs Benefícios• Muito fácil criar testes para algo que ainda não existe• Não tão simples quando a aplicação já existe e está “no ar”.
  12. 12. Aplicaçãonão testada
  13. 13. A Síndrome do “o que estáfuncionando nãose deve mexer”.
  14. 14. Quebre a aplicação!• Criamos testes simples que passem• Teste o que está em produção• Cobertura de testes• O que é crítico?• Especificação• O que falta testar?• Testes de Trollagem
  15. 15. Acredite:Sua aplicação vai falhar!
  16. 16. Já viu essa síndrome?• Não vai ao médico pra evitar descobrir um mal grave• Pode haver um problema latente que vai falhar em um momento crítico• Pode acabar em morte
  17. 17. Na aplicação• Não testamos para não descobrir o que falha• Há problemas latentes que vão falhar em momentos críticos (Por exemplo: um sistema de pagamento do seu e-commerce)• Sua empresa morre (vai a falência)
  18. 18. Estabeleça o que é crítico• Quão crítico é cada parte do seu sistema?• Se não funcionar, quais as consequências?
  19. 19. Alto Ri sc o C Ri rí t sc ico o deOcorrência Ri ní sc ve o ml de éd ba io ix o ní ve Baixo l Baixo Impacto Alto Gerenciamento de Risco http://bit.ly/11tTwN
  20. 20. Automatização• --Retrabalho• --Surpresas• Mais tempo para o que é interessante• Menos tempo para testar tudo novamente
  21. 21. Automatização• --Retrabalho• --Surpresas• Mais tempo para o que é interessante• Menos tempo para testar tudo novamente
  22. 22. Metodologias Ágeis• Aplicar testes é uma rotina contida em Metodologias Ágeis• Testes não dependem de metodologias ágeis• Ex.: jQuery
  23. 23. FuncionaFaz o que deveria
  24. 24. Esse código funciona! • Um código pode funcionar perfeitamente • Estar 100% testado • e não cumprir 10% do seu papel
  25. 25. Fluxo
  26. 26. EspecificaçãoFluxo
  27. 27. Especificação Plano de TestesFluxo
  28. 28. Especificação Plano de TestesFluxo Testes
  29. 29. Validação
  30. 30. ValidaçãoPlano de Testes
  31. 31. ValidaçãoPlano de Testes Especificação
  32. 32. ValidaçãoPlano de Testes Testes Especificação
  33. 33. ValidaçãoPlano de Testes Testes Especificação Aplicação
  34. 34. Testes não validam especificação!Testes não criam especificação!
  35. 35. Testes vs Especificação• Se os testes validassem especificação, não poderiamos prever correções de bugs e comportamentos de ambientes.• Bugs não fazem parte de uma especificação.
  36. 36. Teste que Falha Código Refatorar Baby Steps (Testes Unitários)
  37. 37. Sempre em Baby Steps• Ótimo para pegar o ritmo• função 1, 2, 3, pin• Treino do Lutador
  38. 38. Cobertura de Código
  39. 39. function foo( bar ) { if ( bar ) { console.log( yes! ); else { console.log( no! ); }}
  40. 40. function foo( bar ) { if ( bar ) { console.log( yes! ); else { console.log( no! ); }}
  41. 41. function foo( bar ) { if ( bar ) { console.log( yes! ); else { console.log( no! ); }}
  42. 42. function foo( bar ) { if ( bar ) { console.log( yes! ); else { console.log( no! ); }}
  43. 43. function foo( bar ) { if ( bar ) { console.log( yes! ); else { console.log( no! ); }}
  44. 44. function foo( bar ) { if ( bar ) { console.log( yes! ); else { console.log( no! ); }}
  45. 45. Código 100% coberto por testes!
  46. 46. • JSCoverage• CoverJS
  47. 47. Tudo é testável• Complexidade vs Criticidade• window.location.replace()
  48. 48. JSTestes em JavaScript
  49. 49. Testes UnitáriosInterface FuncionaisDesempenho Integração
  50. 50. Open Webvários ambientes
  51. 51. FirefoxChrome Opera IE 8, 9[, 10, ...]
  52. 52. FirefoxChrome Mobile Opera IE 8, 9[, 10, ...]
  53. 53. PhantomJS Webkit
  54. 54. Ferramentas QUnit NodeUnitMocha Vows Jasmine
  55. 55. Estilos de TestesTDD BDD Exports
  56. 56. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  57. 57. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  58. 58. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  59. 59. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  60. 60. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  61. 61. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  62. 62. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  63. 63. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  64. 64. TDDmodule( "Basics" );test( "hello test", function() {  ok( 1 == "1", "Passed!" );}); http://qunitjs.com/
  65. 65. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  66. 66. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  67. 67. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  68. 68. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  69. 69. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  70. 70. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  71. 71. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  72. 72. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  73. 73. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  74. 74. BDDdescribe("A suite", function() { it("spec with an expectation", function(){ expect(true).toBe(true); });});
  75. 75. BDDdescribe("A suite", function() { it("spec with an expectation", function(){ expect(true).toBe(true); });});
  76. 76. BDDdescribe("A suite", function() { it("spec with an expectation", function(){ expect(true).toBe(true); });});
  77. 77. BDDdescribe("A suite", function() { it("spec with an expectation", function(){ expect(true).toBe(true); });});
  78. 78. BDDdescribe("A suite", function() { it("spec with an expectation", function(){ expect(true).toBe(true); });});
  79. 79. BDDdescribe("A suite", function() { it("spec with an expectation", function(){ expect(true).toBe(true); });});
  80. 80. Exportsmodule.exports = { test1: function (test) { test.equals(this.foo, bar); test.done(); }};
  81. 81. Exportsmodule.exports = { test1: function (test) { test.equals(this.foo, bar); test.done(); }};
  82. 82. Exportsmodule.exports = { test1: function (test) { test.equals(this.foo, bar); test.done(); }};
  83. 83. Exportsmodule.exports = { test1: function (test) { test.equals(this.foo, bar); test.done(); }};
  84. 84. Exportsmodule.exports = { test1: function (test) { test.equals(this.foo, bar); test.done(); }};
  85. 85. Comocomeçar?
  86. 86. HTML Estático JavaScript Testes
  87. 87. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <div id="qunit-fixtures"> <div id="foo">bar</div> </div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  88. 88. <!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>QUnit Example</title>  <link rel="stylesheet" href="/t/qunit.css"></head><body>  <div id="qunit"></div>  <div id="qunit-fixtures"> <div id="foo">bar</div> </div>  <script src="/t/qunit.js"></script> <script src="/js/script.js"></script>  <script src="/t/unit/tests.js"></script></body></html>
  89. 89. Código testado tem bom desempenho?• Testes unitários não medem desempenho• Existem testes de desempenho• Código sem erros pode evitar lentidão
  90. 90. DexterJS
  91. 91. Dexter.spy
  92. 92. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );} http://jsbin.com/osijuq/7/edit
  93. 93. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );} http://jsbin.com/osijuq/7/edit
  94. 94. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );} http://jsbin.com/osijuq/7/edit
  95. 95. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );} http://jsbin.com/osijuq/7/edit
  96. 96. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );} http://jsbin.com/osijuq/7/edit
  97. 97. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );} http://jsbin.com/osijuq/7/edit
  98. 98. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );} http://jsbin.com/osijuq/7/edit
  99. 99. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  100. 100. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  101. 101. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  102. 102. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  103. 103. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  104. 104. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  105. 105. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  106. 106. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  107. 107. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  108. 108. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  109. 109. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  110. 110. test( carly(), 4, function() { var spy = Dexter.spy( window, carly, function( arg1 ) { equal( arg1, crazy!, me sad got crazy! ); }); meSad( false ); equal( spy.called, 1, carly was called once ); spy.callback = 0; equal( meSad( true ), Call me maybe?, keep asking ); equal( spy.called, 2, carly called again! ); spy.restore();});
  111. 111. Dexter.stub
  112. 112. function carly( crazy ) { if ( typeof ( crazy ) === number ) { return Call me maybe?; } else { return Hey, I just met you!, and this is + crazy; }}function meSad( maybe ) { return carly( maybe ? 5555555 : crazy! );}
  113. 113. test( stubbed carly(), 1, function() { var stub = Dexter.stub( window, carly, function() { return relax; }); equal( meSad( true ), relax, stubbed carly! ); stub.restore();});
  114. 114. test( stubbed carly(), 1, function() { var stub = Dexter.stub( window, carly, function() { return relax; }); equal( meSad( true ), relax, stubbed carly! ); stub.restore();});
  115. 115. test( stubbed carly(), 1, function() { var stub = Dexter.stub( window, carly, function() { return relax; }); equal( meSad( true ), relax, stubbed carly! ); stub.restore();});
  116. 116. test( stubbed carly(), 1, function() { var stub = Dexter.stub( window, carly, function() { return relax; }); equal( meSad( true ), relax, stubbed carly! ); stub.restore();});
  117. 117. test( stubbed carly(), 1, function() { var stub = Dexter.stub( window, carly, function() { return relax; }); equal( meSad( true ), relax, stubbed carly! ); stub.restore();});
  118. 118. test( stubbed carly(), 1, function() { var stub = Dexter.stub( window, carly, function() { return relax; }); equal( meSad( true ), relax, stubbed carly! ); stub.restore();});
  119. 119. test( stubbed carly(), 1, function() { var stub = Dexter.stub( window, carly, function() { return relax; }); equal( meSad( true ), relax, stubbed carly! ); stub.restore();});
  120. 120. Dexter.fakeXHR
  121. 121. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  122. 122. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  123. 123. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  124. 124. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  125. 125. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  126. 126. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  127. 127. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  128. 128. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  129. 129. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  130. 130. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  131. 131. test( a fakeXHR, 2, function() { var fakeXHR = Dexter.fakeXHR(); $.get( /ajax.url, function() { ok( true, ajax completed ); }); equal( fakeXHR.requests.length, 1, requests === 1 ); fakeXHR.respond({ body : this is the ajax returned text, headers : { foo2 : bar2 }, status : 200 });});
  132. 132. Começar a criar testes?
  133. 133. Experimente!
  134. 134. Referências• Coding Dojo• Inicialize um projeto com o GruntJS• TDD - Kent Back• Engenharia de Software - Roger S Pressman• Testable JavaScript - Mark Ethan Trostler *
  135. 135. Obrigado! @leobalter leo@balter.com.br JShttp://search.cpan.org/~leobalter/ • @garu_rj • @blabos • @aoqfonseca

×