Testgetriebene Entwicklung      mit JavaScript  Tobias Bosch & Stefan Scheidt   OPITZ CONSULTING GmbH
Wer sind wir?tobias.bosch@opitz-consulting.com            (@tigbro)stefan.scheidt@opitz-consulting.com          (@stefansc...
Mission                                                        MärkteWir entwickeln gemeinsam mit allen                   ...
Wer sind Sie?
In diesem Vortrag geht‘s um ...  ... automatisiertes Testen      ... durch Entwickler
Warum testen?
Warum JavaScript-Code testen?
Laufzeitumgebungen für       JavaScript                         ...
In diesem Vortrag:Icon Set by Paul Irish (http://paulirish.com/2010/high-res-browser-icons/)
Unser Beispiel
Tests formulieren
„Klassisch“ mit xUnit-Asserts   „BDD-Style“ à la RSpec
Demo: BDD mit Jasmine
Hello Jasmine!describe("parseFloat", function() {      it("should return undefined for undefined", function () {          ...
Hello Jasmine!describe("parseFloat", function() {      it("should return undefined for undefined", function () {          ...
Hello Jasmine!describe("parseFloat", function() {      it("should return undefined for undefined", function () {          ...
Hello Jasmine!describe("parseFloat", function() {      it("should return undefined for undefined", function () {          ...
Hello Jasmine!  expect(x).toEqual(y);    expect(x).toBe(y); expect(x).toBeDefined();expect(x).toBeUndefined(); expect(x).t...
Hello Jasmine!
Fortgeschrittene Konzepte
Spies
Spiesdescribe("execute fadein", function() {    it("should eventually set opacity to 1", function () {        var element ...
Spiesdescribe("execute fadein", function() {    it("should eventually set opacity to 1", function () {        var element ...
Spiesdescribe("execute fadein", function() {    it("should eventually set opacity to 1", function () {        var element ...
Spiesdescribe("execute fadein", function() {    it("should eventually set opacity to 1", function () {        var element ...
Spiesdescribe("execute fadein", function() {    it("should eventually set opacity to 1", function () {        var element ...
Spiesdescribe("execute fadein", function() {    it("should eventually set opacity to 1", function () {        var element ...
Spiesdescribe("execute fadein", function() {    it("should eventually set opacity to 1", function () {        var element ...
Funktion                    Der Spy soll ...spy.andCallThrough()                            ... die ursprüngliche Funktion...
Funktion                      Prüft, ob der Spy ...toHaveBeenCalled()            ... aufrufen wurde                       ...
Asynchrone Tests
Asynchrone Testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");    s...
Asynchrone Testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");    s...
Asynchrone Testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");    s...
Asynchrone Testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");    s...
Asynchrone Testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");    s...
UI-Tests
describeUi("index", "/js-fadein/index.html", function () {      it("should fade in hello div on button click", function ()...
describeUi("index", "/js-fadein/index.html", function () {      it("should fade in hello div on button click", function ()...
describeUi("index", "/js-fadein/index.html", function () {      it("should fade in hello div on button click", function ()...
describeUi("index", "/js-fadein/index.html", function () {      it("should fade in hello div on button click", function ()...
describeUi("index", "/js-fadein/index.html", function () {      it("should fade in hello div on button click", function ()...
describeUi("index", "/js-fadein/index.html", function () {      it("should fade in hello div on button click", function ()...
Testausführung automatisieren
Pro              Contra          Beispiele                          - Schwerer zu   Im       Laufen in                    ...
Browser fernsteuern
JsTestDriverhttp://code.google.com/p/js-test-driver/
Demo: JsTestDriver
FazitEs gibt ein umfangreiches Toolset zum Testen             von JavaScript-Code.             Testen Sie Ihren Code!Teste...
LinksJasmine        http://pivotal.github.com/jasmine/Jasmine UI     https://github.com/tigbro/jasmine-uijs-fadein      ht...
saturated writing    (By Eduordo, http://www.flickr.com/photos/tnarik/366393127/)                           Smiley Keyboar...
Stamp Collector(By C. Castillo, http://www.flickr.com/photos/carolinedecastillo/2750577684/)                              ...
Vielen Dankfür Ihr Interesse!     @tigbro  @stefanscheidt
Upcoming SlideShare
Loading in...5
×

Testgetriebene Entwicklung mit JavaScript – Jax 2012

2,089

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,089
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

Transcript of "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

×