Tobias	  Bosch	  &	  Stefan	  Scheidt	  /	  OPITZ	  CONSULTING	  GmbH	  Test-­‐Driven	  JavaScript	  Development	  
Wer	  sind	  wir?	   tobias.bosch@opitz-­‐consulLng.com	                (@Lgbro)	                   	  stefan.scheidt@opit...
Märkte            Kunden                                               Leistungs-              Fakten                     ...
Wer	  sind	  Sie?	  
In	  diesem	  Vortrag	  geht‘s	  um...	                         	        ...automaLsiertes	  Testen	            ...durch	 ...
Warum	  testen?	  
Warum	  JavaScript-­‐Code	  testen?	  
Laufzeitumgebungen	  für	         JavaScript	             	             	             	             	             	       ...
In	  diesem	  Vortrag:	                               	                               	                               	   ...
Tests	  formulieren	  
„Klassisch“	  mit	  xUnit-­‐Asserts	                        	                        	     „BDD-­‐Style“	  	  à	  la	  RSp...
Demo:	  BDD	  mit	  Jasmine	  
Hello	  Jasmine!	  describe("parseFloat",	  function()	  {	  	  	  	  	  	  it("should	  return	  undefined	  for	  undefi...
Hello	  Jasmine!	  describe("parseFloat",	  function()	  {	                                                               ...
Hello	  Jasmine!	  describe("parseFloat",	  function()	  {	  	  	  	  	  	  it("should	  return	  undefined	  for	  undefi...
Hello	  Jasmine!	  describe("parseFloat",	  function()	  {	  	  	  	  	  	  it("should	  return	  undefined	  for	  undefi...
Hello	  Jasmine!	       her	  Matc             expect(x).toEqual(y);	                     expect(x).toBe(y);	             ...
Hello	  Jasmine!	                          Spec	                                   Runn                                   ...
Fortgeschriaene	  Konzepte	  
Spies	  
Spies	  describe("execute	  fadein",	  function()	  {	  	  	  	  	  	  it("should	  eventually	  set	  opacity	  to	  1",	...
Spies	  describe("execute	  fadein",	  function()	  {	  	  	  	  	  	  it("should	  eventually	  set	  opacity	  to	  1",	...
Spies	  describe("execute	  fadein",	  function()	  {	                                                                    ...
Spies	  describe("execute	  fadein",	  function()	  {	                                                                    ...
Spies	  describe("execute	  fadein",	  function()	  {	                                                                    ...
Spies	  describe("execute	  fadein",	  function()	  {	  	  	  	  	  	  it("should	  eventually	  set	  opacity	  to	  1",	...
Spies	  describe("execute	  fadein",	  function()	  {	  	  	  	  	  	  it("should	  eventually	  set	  opacity	  to	  1",	...
FunkLon	                       Der	  Spy	  soll...	  spy.andCallThrough()	          ...	  die	  ursprüngliche	  FunkLon	  ...
FunkLon	                              Prüb,	  ob	  der	  Spy...	  toHaveBeenCalled()	                   ...	  aufrufen	  w...
Asynchrone	  Tests	  
Asynchrone	  Tests	  it("should	  eventually	  set	  opacity	  to	  1",	  function()	  {	  	  	  	  	  var	  element	  =	 ...
Asynchrone	  Tests	  it("should	  eventually	  set	  opacity	  to	  1",	  function()	  {	  	  	  	  	  var	  element	  =	 ...
Asynchrone	  Tests	  it("should	  eventually	  set	  opacity	  to	  1",	  function()	  {	  	  	  	  	  var	  element	  =	 ...
Asynchrone	  Tests	  it("should	  eventually	  set	  opacity	  to	  1",	  function()	  {	  	  	  	  	  var	  element	  =	 ...
Asynchrone	  Tests	  it("should	  eventually	  set	  opacity	  to	  1",	  function()	  {	  	  	  	  	  var	  element	  =	 ...
UI-­‐Tests	  
it("should	  fade	  in	  hello	  div	  on	  button	  click",	  function	  ()	  {	  	  	  	  	  var	  win,	  field,	  butto...
it("should	  fade	  in	  hello	  div	  on	  button	  click",	  function	  ()	  {	  	  	  	  	  var	  win,	  field,	  butto...
it("should	  fade	  in	  hello	  div	  on	  button	  click",	  function	  ()	  {	  	  	  	  	  var	  win,	  field,	  butto...
it("should	  fade	  in	  hello	  div	  on	  button	  click",	  function	  ()	  {	  	  	  	  	  var	  win,	  field,	  butto...
it("should	  fade	  in	  hello	  div	  on	  button	  click",	  function	  ()	  {	  	  	  	  	  var	  win,	  field,	  butto...
it("should	  fade	  in	  hello	  div	  on	  button	  click",	  function	  ()	  {	  	  	  	  	  var	  win,	  field,	  butto...
it("should	  fade	  in	  hello	  div	  on	  button	  click",	  function	  ()	  {	  	  	  	  	  var	  win,	  field,	  butto...
Testausführung	  automaLsieren	  
Pro	                        Contra	                       Beispiele	                                                  -­‐	...
Browser	  fernsteuern	  
JsTestDriver	  h4p://code.google.com/p/js-­‐test-­‐driver/	  
Demo:	  JsTestDriver	  
Fazit	   Es	  gibt	  ein	  umfangreiches	  Toolset	  zum	  Testen	                          von	  JavaScript-­‐Code.	     ...
Links	  Jasmine	           hap://pivotal.github.com/jasmine/	  Jasmine	  UI	     haps://github.com/Lgbro/jasmine-­‐ui	  Js...
saturated	  wriLng	          (By	  Eduordo,	  hap://www.flickr.com/photos/tnarik/366393127/)	                              ...
Stamp	  Collector	  (By	  C.	  CasLllo,	  hap://www.flickr.com/photos/carolinedecasLllo/2750577684/)	                      ...
Besuchen	  Sie	  uns	  Morgen	  beim	  Vortrag	                             	      JavaScript	  Data	  Binding	        mit...
Vielen	  Dank	  für	  Ihr	  Interesse!	            	         @Lgbro	        @beezlebug	  
Test driven java script development
Upcoming SlideShare
Loading in...5
×

Test driven java script development

1,219

Published on

JavaScript ist eine sehr dynamische Sprache und verhält sich zudem je nach Browser unterschiedlich. Daher sind automatisierte Tests besonders wertvoll. Dieser Vortrag zeigt, wie Cross-Browser-Tests für JavaScript entwickelt werden können.

Vortrag von der MobileTech Conference 2011

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,219
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Test driven java script development

  1. 1. Tobias  Bosch  &  Stefan  Scheidt  /  OPITZ  CONSULTING  GmbH  Test-­‐Driven  JavaScript  Development  
  2. 2. Wer  sind  wir?   tobias.bosch@opitz-­‐consulLng.com   (@Lgbro)    stefan.scheidt@opitz-­‐consulLng.com   (@beezlebug)    
  3. 3. Märkte Kunden Leistungs- Fakten angebotn Java n Branchen- n IT-Strategie n Gründung 1990n SOA übergreifend n Beratung n 400 Mitarbeitern ORACLE n Über 600 n Implementierung n 8 Standorte in D/n BI/DWH Kunden n Betrieb PLn Outtasking n Training Industrie / Versorger / Handel / Logistik / Telekommunikation Dienstleistungen 29% 29% 42% Öffentliche Auftraggeber / Banken & Versicherungen / Vereine & Verbände © OPITZ CONSULTING GmbH 2011 Seite 3
  4. 4. Wer  sind  Sie?  
  5. 5. In  diesem  Vortrag  geht‘s  um...     ...automaLsiertes  Testen   ...durch  Entwickler  
  6. 6. Warum  testen?  
  7. 7. Warum  JavaScript-­‐Code  testen?  
  8. 8. Laufzeitumgebungen  für   JavaScript             ...  
  9. 9. In  diesem  Vortrag:            Icon  Set  by  Paul  Irish  (h4p://paulirish.com/2010/high-­‐res-­‐browser-­‐icons/)    
  10. 10. Tests  formulieren  
  11. 11. „Klassisch“  mit  xUnit-­‐Asserts       „BDD-­‐Style“    à  la  RSpec  
  12. 12. Demo:  BDD  mit  Jasmine  
  13. 13. Hello  Jasmine!  describe("parseFloat",  function()  {            it("should  return  undefined  for  undefined",  function  ()  {                  expect(util.parseFloat(undefined)).toBeUndefined();          });            it("should  return  0  for  empty  string",  function  ()  {                  expect(util.parseFloat()).toEqual(0);          });            it("should  return  number  for  number  strings",  function  ()  {                  expect(util.parseFloat(1.5)).toEqual(1.5);          });            //  ...    });  
  14. 14. Hello  Jasmine!  describe("parseFloat",  function()  {   Suite            it("should  return  undefined  for  undefined",  function  ()  {                  expect(util.parseFloat(undefined)).toBeUndefined();          });            it("should  return  0  for  empty  string",  function  ()  {                  expect(util.parseFloat()).toEqual(0);          });            it("should  return  number  for  number  strings",  function  ()  {                  expect(util.parseFloat(1.5)).toEqual(1.5);          });            //  ...    });  
  15. 15. Hello  Jasmine!  describe("parseFloat",  function()  {            it("should  return  undefined  for  undefined",  function  ()  {                  expect(util.parseFloat(undefined)).toBeUndefined();          });     Sp cs        it("should  return  0  for  empty  string",  function  ()  {   e                expect(util.parseFloat()).toEqual(0);            });            it("should  return  number  for  number  strings",  function  ()  {                  expect(util.parseFloat(1.5)).toEqual(1.5);          });            //  ...    });  
  16. 16. Hello  Jasmine!  describe("parseFloat",  function()  {            it("should  return  undefined  for  undefined",  function  ()  {                  expect(util.parseFloat(undefined)).toBeUndefined();          });     Matc        it("should  return  0  for  empty  string",  function  ()  {                  expect(util.parseFloat()).toEqual(0);   her          });            it("should  return  number  for  number  strings",  function  ()  {                  expect(util.parseFloat(1.5)).toEqual(1.5);          });            //  ...    });  
  17. 17. Hello  Jasmine!   her  Matc expect(x).toEqual(y);   expect(x).toBe(y);   expect(x).toBeDefined();   expect(x).toBeUndefined();   expect(x).toBeTruthy();   expect(x).toBeFalsy();   ...  
  18. 18. Hello  Jasmine!   Spec   Runn er  
  19. 19. Fortgeschriaene  Konzepte  
  20. 20. Spies  
  21. 21. Spies  describe("execute  fadein",  function()  {            it("should  eventually  set  opacity  to  1",  function  ()  {                  var  element  =  document.createElement("div");                  spyOn(window,  setTimeout).andCallFake(                          function(callback)  {                                  callback();                          });                  spyOn(util,  opacity);                  fadein.execute(element);                  expect(util.opacity.mostRecentCall.args[1]).toEqual(1);          });    });  
  22. 22. Spies  describe("execute  fadein",  function()  {            it("should  eventually  set  opacity  to  1",  function  ()  {                  var  element  =  document.createElement("div");                  spyOn(window,  setTimeout).andCallFake(                          function(callback)  {                                  callback();                          });                  spyOn(util,  opacity);                  fadein.execute(element);                  expect(util.opacity.mostRecentCall.args[1]).toEqual(1);          });    });  
  23. 23. Spies  describe("execute  fadein",  function()  {   Arran   ge          it("should  eventually  set  opacity  to  1",  function  ()  {                  var  element  =  document.createElement("div");                  spyOn(window,  setTimeout).andCallFake(                          function(callback)  {                                  callback();                          });                  spyOn(util,  opacity);                  fadein.execute(element);                  expect(util.opacity.mostRecentCall.args[1]).toEqual(1);          });    });  
  24. 24. Spies  describe("execute  fadein",  function()  {   Arran          it("should  eventually  set  opacity  to  1",  function  ()  {   ge                  var  element  =  document.createElement("div");                  spyOn(window,  setTimeout).andCallFake(                          function(callback)  {                                  callback();                          });                  spyOn(util,  opacity);   //  waits  for  delay  seconds                  fadein.execute(element);   //  then  calls  callback                  expect(util.opacity.mostRecentCall.args[1]).toEqual(1);   window.setTimeout  =  function  (callback,  delay)  {          });          ...     };    });  
  25. 25. Spies  describe("execute  fadein",  function()  {   Arran          it("should  eventually  set  opacity  to  1",  function  ()  {   ge                  var  element  =  document.createElement("div");   //  set  opacity  of  element  to  opacity   util.opacity  =  function  (element,  opacity)  {                  spyOn(window,  setTimeout).andCallFake(          ...                          function(callback)  {   };                                    callback();                          });                  spyOn(util,  opacity);                  fadein.execute(element);                  expect(util.opacity.mostRecentCall.args[1]).toEqual(1);          });    });  
  26. 26. Spies  describe("execute  fadein",  function()  {            it("should  eventually  set  opacity  to  1",  function  ()  {                  var  element  =  document.createElement("div");                  spyOn(window,  setTimeout).andCallFake(                          function(callback)  {                                  callback();                          });   Act                  spyOn(util,  opacity);                  fadein.execute(element);                  expect(util.opacity.mostRecentCall.args[1]).toEqual(1);          });    });  
  27. 27. Spies  describe("execute  fadein",  function()  {            it("should  eventually  set  opacity  to  1",  function  ()  {                  var  element  =  document.createElement("div");   //  set  opacity  of  element  to  opacity   util.opacity  =  function  (element,  opacity)  {                  spyOn(window,  setTimeout).andCallFake(          ...                          function(callback)  {   };                                    callback();                          });   Asser                spyOn(util,  opacity);   t                  fadein.execute(element);                  expect(util.opacity.mostRecentCall.args[1]).toEqual(1);          });    });  
  28. 28. FunkLon   Der  Spy  soll...  spy.andCallThrough()   ...  die  ursprüngliche  FunkLon   aufrufen  spy.andReturn(argument)   ...  das  übergebene  Argumente   zurückgeben  spy.andThrow(exception)   ...  die  übergebene  ExcepLon   werfen  spy.andCallFake(function)   ...  die  übergebene  FunkLon   aufrufen   FunkLonen  von  Spies  
  29. 29. FunkLon   Prüb,  ob  der  Spy...  toHaveBeenCalled()   ...  aufrufen  wurde  toHaveBeenCalledWith(args)   ...  mit  den  übergebenen   Argumenten  aufgerufen  wurde   Matcher  für  Spies  FunkLon   Bedeutung  spy.callCount   Anzahl  der  Aufrufe  spy.argsForCall[i]   Argumente  des  i-­‐ten  Aufrufs  spy.mostRecentCall.args   Argumente  des  letzten  Aufrufs   Eigenschaben  von  Spies  
  30. 30. Asynchrone  Tests  
  31. 31. Asynchrone  Tests  it("should  eventually  set  opacity  to  1",  function()  {          var  element  =  document.createElement("div");          spyOn(util,  opacity);          runs(function()  {                  fadein.execute(element);          });          waitsFor(function  ()  {                  return  opacitySpy.mostRecentCall.args[1]  ===  1;          });          runs(function()  {                  //  some  other  expectations                  expect(opacitySpy.mostRecentCall.args[1]).toEqual(1);            });  });  
  32. 32. Asynchrone  Tests  it("should  eventually  set  opacity  to  1",  function()  {          var  element  =  document.createElement("div");          spyOn(util,  opacity);   Arran        runs(function()  {   ge                  fadein.execute(element);          });          waitsFor(function  ()  {                  return  opacitySpy.mostRecentCall.args[1]  ===  1;          });          runs(function()  {                  //  some  other  expectations                  expect(opacitySpy.mostRecentCall.args[1]).toEqual(1);            });  });  
  33. 33. Asynchrone  Tests  it("should  eventually  set  opacity  to  1",  function()  {          var  element  =  document.createElement("div");          spyOn(util,  opacity);          runs(function()  {   Act                  fadein.execute(element);          });          waitsFor(function  ()  {                  return  opacitySpy.mostRecentCall.args[1]  ===  1;          });          runs(function()  {                  //  some  other  expectations                  expect(opacitySpy.mostRecentCall.args[1]).toEqual(1);            });  });  
  34. 34. Asynchrone  Tests  it("should  eventually  set  opacity  to  1",  function()  {          var  element  =  document.createElement("div");          spyOn(util,  opacity);          runs(function()  {                  fadein.execute(element);   Wait        });   ...          waitsFor(function  ()  {                  return  opacitySpy.mostRecentCall.args[1]  ===  1;          });          runs(function()  {                  //  some  other  expectations   //  set  opacity  of  element  to  opacity                  expect(opacitySpy.mostRecentCall.args[1]).toEqual(1);     util.opacity  =  function  (element,  opacity)  {          });          ...  });   };    
  35. 35. Asynchrone  Tests  it("should  eventually  set  opacity  to  1",  function()  {          var  element  =  document.createElement("div");          spyOn(util,  opacity);          runs(function()  {                  fadein.execute(element);          });          waitsFor(function  ()  {                  return  opacitySpy.mostRecentCall.args[1]  ===  1;          });   Asser        runs(function()  {   t                  //  some  other  expectations                  expect(opacitySpy.mostRecentCall.args[1]).toEqual(1);            });  });  
  36. 36. UI-­‐Tests  
  37. 37. it("should  fade  in  hello  div  on  button  click",  function  ()  {          var  win,  field,  button;          loadHtml("/js-­‐fadein/index.html");          runs(function()  {                  win  =  testwindow();                  field  =  win.document.getElementById(hello);                  button  =  win.document.getElementById(fadein);          });          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(0);                  jasmine.ui.simulate(button,  click);          });          waitsForAsync();          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(1);          });  });    UI-­‐Test  mit  Jasmine-­‐UI    
  38. 38. it("should  fade  in  hello  div  on  button  click",  function  ()  {          var  win,  field,  button;   .          loadHtml("/js-­‐fadein/index.html");   age.. dex  p        runs(function()  {   n The  i                win  =  testwindow();                  field  =  win.document.getElementById(hello);                  button  =  win.document.getElementById(fadein);          });          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(0);                  jasmine.ui.simulate(button,  click);          });          waitsForAsync();          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(1);          });  });    UI-­‐Test  mit  Jasmine-­‐UI    
  39. 39. it("should  fade  in  hello  div  on  button  click",  function  ()  {          var  win,  field,  button;          loadHtml("/js-­‐fadein/index.html");   Arran        runs(function()  {   ge,  P art  1                  win  =  testwindow();                  field  =  win.document.getElementById(hello);                  button  =  win.document.getElementById(fadein);          });          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(0);                  jasmine.ui.simulate(button,  click);          });          waitsForAsync();          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(1);          });  });    UI-­‐Test  mit  Jasmine-­‐UI    
  40. 40. it("should  fade  in  hello  div  on  button  click",  function  ()  {          var  win,  field,  button;          loadHtml("/js-­‐fadein/index.html");   Arran        runs(function()  {   ge,  P art  2                  win  =  testwindow();                  field  =  win.document.getElementById(hello);                  button  =  win.document.getElementById(fadein);          });          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(0);                  jasmine.ui.simulate(button,  click);          });          waitsForAsync();          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(1);          });  });    UI-­‐Test  mit  Jasmine-­‐UI    
  41. 41. it("should  fade  in  hello  div  on  button  click",  function  ()  {          var  win,  field,  button;          loadHtml("/js-­‐fadein/index.html");          runs(function()  {                  win  =  testwindow();                  field  =  win.document.getElementById(hello);                  button  =  win.document.getElementById(fadein);          });   Act          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(0);                  jasmine.ui.simulate(button,  click);          });          waitsForAsync();          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(1);          });  });    UI-­‐Test  mit  Jasmine-­‐UI    
  42. 42. it("should  fade  in  hello  div  on  button  click",  function  ()  {          var  win,  field,  button;          loadHtml("/js-­‐fadein/index.html");          runs(function()  {                  win  =  testwindow();                  field  =  win.document.getElementById(hello);                  button  =  win.document.getElementById(fadein);          });          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(0);                  jasmine.ui.simulate(button,  click);          });   Wait ...          waitsForAsync();          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(1);          });  });    UI-­‐Test  mit  Jasmine-­‐UI    
  43. 43. it("should  fade  in  hello  div  on  button  click",  function  ()  {          var  win,  field,  button;          loadHtml("/js-­‐fadein/index.html");          runs(function()  {                  win  =  testwindow();                  field  =  win.document.getElementById(hello);                  button  =  win.document.getElementById(fadein);          });          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(0);                  jasmine.ui.simulate(button,  click);          });   Asser        waitsForAsync();   t          runs(function  ()  {                  expect(win.util.opacity(field)).toEqual(1);          });  });    UI-­‐Test  mit  Jasmine-­‐UI    
  44. 44. Testausführung  automaLsieren  
  45. 45. Pro   Contra   Beispiele   -­‐  Schwerer  zu   Im   Laufen  in    QUnit   automaLsieren  Browser   ProdukLons-­‐  YUI  Test   testen   -­‐  Schwerer  in  CI   umgebung    Jasmine   einzubeaen   -­‐  Leicht  zu    Envjs  Headless   automaLsieren   Browser  wird    PhantomJS  Browser   -­‐    Leicht  in  CI   nur  simuliert    Zombie.js   einzubeaen    HtmlUnit  
  46. 46. Browser  fernsteuern  
  47. 47. JsTestDriver  h4p://code.google.com/p/js-­‐test-­‐driver/  
  48. 48. Demo:  JsTestDriver  
  49. 49. Fazit   Es  gibt  ein  umfangreiches  Toolset  zum  Testen   von  JavaScript-­‐Code.     Testen  Sie  Ihren  Code!  Testen  Sie  insbesondere  Ihren  JavaScript-­‐Code!   Sie  haben  keine  Ausrede...  
  50. 50. Links  Jasmine   hap://pivotal.github.com/jasmine/  Jasmine  UI   haps://github.com/Lgbro/jasmine-­‐ui  JsTestDriver   hap://code.google.com/p/js-­‐test-­‐driver/  
  51. 51. saturated  wriLng   (By  Eduordo,  hap://www.flickr.com/photos/tnarik/366393127/)     Smiley  Keyboard   (By  ~Prescoa,  hap://www.flickr.com/photos/ppym1/93571524/)     Spyhole,  Paris  (By  smith  of  smiths,  hap://www.flickr.com/photos/hesketh/232015302/)     Sorta  synchronised  diving   (By  Aaron  Retz,  hap://www.flickr.com/photos/aretz/309469339/)  
  52. 52. Stamp  Collector  (By  C.  CasLllo,  hap://www.flickr.com/photos/carolinedecasLllo/2750577684/)     bios  [bible]   (By  Gastev,  hap://www.flickr.com/photos/gastev/2174505811/)     Day  276/365:  in  hot  pursuit   (By  Tina  Vega,  hap://www.flickr.com/photos/Lnavega/3066602429/)    
  53. 53. Besuchen  Sie  uns  Morgen  beim  Vortrag     JavaScript  Data  Binding   mit  jQuery  Mobile     um  10:00  Uhr  im  Watordsaal  
  54. 54. Vielen  Dank  für  Ihr  Interesse!     @Lgbro   @beezlebug  
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×