• Save
Testgetriebene Entwicklung mit JavaScript – Jax 2012
 

Like this? Share it with your network

Share

Testgetriebene Entwicklung mit JavaScript – Jax 2012

on

  • 2,397 views

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

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

Statistics

Views

Total Views
2,397
Views on SlideShare
2,397
Embed Views
0

Actions

Likes
3
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Testgetriebene Entwicklung mit JavaScript – Jax 2012 Presentation Transcript

  • 1. Testgetriebene Entwicklung mit JavaScript Tobias Bosch & Stefan Scheidt OPITZ CONSULTING GmbH
  • 2. Wer sind wir?tobias.bosch@opitz-consulting.com (@tigbro)stefan.scheidt@opitz-consulting.com (@stefanscheidt)
  • 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. Wer sind Sie?
  • 5. In diesem Vortrag geht‘s um ... ... automatisiertes Testen ... durch Entwickler
  • 6. Warum testen?
  • 7. Warum JavaScript-Code testen?
  • 8. Laufzeitumgebungen für JavaScript ...
  • 9. In diesem Vortrag:Icon Set by Paul Irish (http://paulirish.com/2010/high-res-browser-icons/)
  • 10. Unser Beispiel
  • 11. Tests formulieren
  • 12. „Klassisch“ mit xUnit-Asserts „BDD-Style“ à la RSpec
  • 13. Demo: BDD mit Jasmine
  • 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. 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. 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. 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. Hello Jasmine! expect(x).toEqual(y); expect(x).toBe(y); expect(x).toBeDefined();expect(x).toBeUndefined(); expect(x).toBeTruthy(); expect(x).toBeFalsy(); ...
  • 19. Hello Jasmine!
  • 20. Fortgeschrittene Konzepte
  • 21. Spies
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. Asynchrone Tests
  • 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. 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. 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. 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. 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. UI-Tests
  • 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. 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. 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. 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. 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. 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. Testausführung automatisieren
  • 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. Browser fernsteuern
  • 47. JsTestDriverhttp://code.google.com/p/js-test-driver/
  • 48. Demo: JsTestDriver
  • 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. 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. 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. 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. Vielen Dankfür Ihr Interesse! @tigbro @stefanscheidt