Testgetriebene Entwicklung mit JavaScript – Jax 2012

2,154
-1

Published on

www.opitz-consulting.com/go/3-4-11

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.
Die Java- und JavaScript-Experten Stefan Scheidt und Tobias Bosch von OPITZ CONSULTING präsentierten diesen Vortrag bei der Jax 2012 am 18.04.2012 in Mainz.

--
Sie möchten mobile Geschäftslösungen in Ihrem Unternehmen nutzen? Wir beraten Sie gerne. Lesen Sie hier mehr zu unseren Leistungen in diesem Bereich und informieren Sie sich zu unserem Workshop für die professionelle Web-App-Entwicklung mit JavaScript: www.opitz-consulting.com/go/3-4-898

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

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

No notes for slide

Testgetriebene Entwicklung mit JavaScript – Jax 2012

  1. 1. Testgetriebene Entwicklung mit JavaScript Tobias Bosch & Stefan Scheidt OPITZ CONSULTING GmbH
  2. 2. Wer sind wir?tobias.bosch@opitz-consulting.com (@tigbro)stefan.scheidt@opitz-consulting.com (@stefanscheidt)
  3. 3. Mission MärkteWir entwickeln gemeinsam mit allen  BranchenübergreifendBranchen Lösungen, die dazu führen, dass  Über 600 Kundensich diese Organisationen besser entwickeln 29%als ihr Wettbewerb. 29% Handel / Logistik / Dienstleistungen Industrie / Versorger /Unsere Dienstleistung erfolgt Telekommunikationpartnerschaftlich und ist auf eine langjährige 42%Zusammenarbeit angelegt. Öffentliche Auftraggeber / Banken und Versicherungen / Vereine und VerbändeLeistungsangebot Eckdaten Business IT Alignment  Gründung 1990 Business Information Management  400 Mitarbeiter Business Process Management  8 Standorte Anwendungsentwicklung SOA und System-Integration IT-Infrastruktur-Management Testgetriebene Entwicklung mit JavaScript © OPITZ CONSULTING GmbH 2011 Seite 3
  4. 4. Wer sind Sie?
  5. 5. In diesem Vortrag geht‘s um ... ... automatisiertes 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 (http://paulirish.com/2010/high-res-browser-icons/)
  10. 10. Unser Beispiel
  11. 11. Tests formulieren
  12. 12. „Klassisch“ mit xUnit-Asserts „BDD-Style“ à la RSpec
  13. 13. Demo: BDD mit Jasmine
  14. 14. 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); }); // ...});
  15. 15. 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); }); // ...});
  16. 16. 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); }); // ...});
  17. 17. 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); }); // ...});
  18. 18. Hello Jasmine! expect(x).toEqual(y); expect(x).toBe(y); expect(x).toBeDefined();expect(x).toBeUndefined(); expect(x).toBeTruthy(); expect(x).toBeFalsy(); ...
  19. 19. Hello Jasmine!
  20. 20. Fortgeschrittene Konzepte
  21. 21. Spies
  22. 22. Spiesdescribe("execute fadein", function() { it("should eventually set opacity to 1", function () { var element = document.createElement("div"); jasmine.Clock.useMock(); spyOn(util, opacity); fadein.execute(element); jasmine.Clock.tick(1000); var mostRecentCall = util.opacity.mostRecentCall; expect(mostRecentCall.args[0]).toBe(element); expect(mostRecentCall.args[1]).toEqual(1); });});
  23. 23. Spiesdescribe("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); var mostRecentCall = util.opacity.mostRecentCall; expect(mostRecentCall.args[0]).toBe(element); expect(mostRecentCall.args[1]).toEqual(1); });});
  24. 24. Spiesdescribe("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); var mostRecentCall = util.opacity.mostRecentCall; expect(mostRecentCall.args[0]).toBe(element); expect(mostRecentCall.args[1]).toEqual(1); });});
  25. 25. Spiesdescribe("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); var mostRecentCall = util.opacity.mostRecentCall; expect(mostRecentCall.args[0]).toBe(element); expect(mostRecentCall.args[1]).toEqual(1); });});
  26. 26. Spiesdescribe("execute fadein", function() { it("should eventually set opacity to 1", function () { var element = document.createElement("div"); spyOn(window,set opacity of element to opacity // setTimeout).andCallFake( util.opacity = function (element, opacity) { function(callback) { ... callback(); }; }); spyOn(util, opacity); fadein.execute(element); var mostRecentCall = util.opacity.mostRecentCall; expect(mostRecentCall.args[0]).toBe(element); expect(mostRecentCall.args[1]).toEqual(1); });});
  27. 27. Spiesdescribe("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); var mostRecentCall = util.opacity.mostRecentCall; expect(mostRecentCall.args[0]).toBe(element); expect(mostRecentCall.args[1]).toEqual(1); });});
  28. 28. Spiesdescribe("execute fadein", function() { it("should eventually set opacity to 1", function () { var element = document.createElement("div"); spyOn(window,set opacity of element to opacity // setTimeout).andCallFake( function(callback) = function (element, opacity) { util.opacity { ... callback(); }); }; spyOn(util, opacity); fadein.execute(element); var mostRecentCall = util.opacity.mostRecentCall; expect(mostRecentCall.args[0]).toBe(element); expect(mostRecentCall.args[1]).toEqual(1); });});
  29. 29. Funktion Der Spy soll ...spy.andCallThrough() ... die ursprüngliche Funktion aufrufen ... das übergebene Argumentespy.andReturn(argument) zurückgeben ... die übergebene Exceptionspy.andThrow(exception) werfenspy.andCallFake(function) ... die übergebene Funktion aufrufen Funktionen von Spies
  30. 30. Funktion Prüft, ob der Spy ...toHaveBeenCalled() ... aufrufen wurde ... mit den übergebenentoHaveBeenCalledWith(args) Argumenten aufgerufen wurde Matcher für SpiesFunktion Bedeutungspy.callCount Anzahl der Aufrufespy.argsForCall[i] Argumente des i-ten Aufrufsspy.mostRecentCall.args Argumente des letzten Aufrufs Eigenschaften von Spies
  31. 31. Asynchrone Tests
  32. 32. Asynchrone Testsit("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); });});
  33. 33. Asynchrone Testsit("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); });});
  34. 34. Asynchrone Testsit("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); });});
  35. 35. Asynchrone Testsit("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 // set opacity of element to opacity expect(opacitySpy.mostRecentCall.args[1]).toEqual(1); { util.opacity = function (element, opacity) }); ...}); };
  36. 36. Asynchrone Testsit("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); });});
  37. 37. UI-Tests
  38. 38. describeUi("index", "/js-fadein/index.html", function () { it("should fade in hello div on button click", function () { var win, field, button; runs(function() { field = document.getElementById(hello); button = document.getElementById(fadein); expect(util.opacity(field)).toEqual(0); simulate(button, click); }); runs(function () { expect(util.opacity(field)).toEqual(1); }); });}); UI-Test mit Jasmine-UI
  39. 39. describeUi("index", "/js-fadein/index.html", function () { it("should fade in hello div on button click", function () { var win, field, button; runs(function() { field = document.getElementById(hello); button = document.getElementById(fadein); expect(util.opacity(field)).toEqual(0); simulate(button, click); }); runs(function () { expect(util.opacity(field)).toEqual(1); }); });}); UI-Test mit Jasmine-UI
  40. 40. describeUi("index", "/js-fadein/index.html", function () { it("should fade in hello div on button click", function () { var win, field, button; runs(function() { field = document.getElementById(hello); button = document.getElementById(fadein); expect(util.opacity(field)).toEqual(0); simulate(button, click); }); runs(function () { expect(util.opacity(field)).toEqual(1); }); });}); UI-Test mit Jasmine-UI
  41. 41. describeUi("index", "/js-fadein/index.html", function () { it("should fade in hello div on button click", function () { var win, field, button; runs(function() { field = document.getElementById(hello); button = document.getElementById(fadein); expect(util.opacity(field)).toEqual(0); simulate(button, click); }); runs(function () { expect(util.opacity(field)).toEqual(1); }); });}); UI-Test mit Jasmine-UI
  42. 42. describeUi("index", "/js-fadein/index.html", function () { it("should fade in hello div on button click", function () { var win, field, button; runs(function() { field = document.getElementById(hello); button = document.getElementById(fadein); expect(util.opacity(field)).toEqual(0); simulate(button, click); }); runs(function () { expect(util.opacity(field)).toEqual(1); }); });}); UI-Test mit Jasmine-UI
  43. 43. describeUi("index", "/js-fadein/index.html", function () { it("should fade in hello div on button click", function () { var win, field, button; runs(function() { field = document.getElementById(hello); button = document.getElementById(fadein); expect(util.opacity(field)).toEqual(0); simulate(button, click); }); runs(function () { expect(util.opacity(field)).toEqual(1); }); });}); UI-Test mit Jasmine-UI
  44. 44. Testausführung automatisieren
  45. 45. Pro Contra Beispiele - Schwerer zu Im Laufen in QUnit automatisierenBrowser Produktions- YUI Test testen - Schwerer in CI umgebung Jasmine einzubetten - Leicht zu EnvjsHeadless automatisieren Browser wird PhantomJSBrowser - Leicht in CI nur simuliert Zombie.js einzubetten HtmlUnit
  46. 46. Browser fernsteuern
  47. 47. JsTestDriverhttp://code.google.com/p/js-test-driver/
  48. 48. Demo: JsTestDriver
  49. 49. FazitEs 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. LinksJasmine http://pivotal.github.com/jasmine/Jasmine UI https://github.com/tigbro/jasmine-uijs-fadein https://github.com/stefanscheidt/js-fadeinJsTestDriver http://code.google.com/p/js-test-driver/
  51. 51. saturated writing (By Eduordo, http://www.flickr.com/photos/tnarik/366393127/) Smiley Keyboard (By ~Prescott, http://www.flickr.com/photos/ppym1/93571524/) Spyhole, Paris(By smith of smiths, http://www.flickr.com/photos/hesketh/232015302/) Sorta synchronised diving (By Aaron Retz, http://www.flickr.com/photos/aretz/309469339/)
  52. 52. Stamp Collector(By C. Castillo, http://www.flickr.com/photos/carolinedecastillo/2750577684/) bios [bible] (By Gastev, http://www.flickr.com/photos/gastev/2174505811/) Day 276/365: in hot pursuit (By Tina Vega, http://www.flickr.com/photos/tinavega/3066602429/)
  53. 53. Vielen Dankfür Ihr Interesse! @tigbro @stefanscheidt

×