Your SlideShare is downloading. ×
Test Driven JavaScript DevelopmentTobias BoschOPITZ CONSULTING Deutschland GmbH
Who am I?tobias.bosch@opitz-consulting.com            (@tigbro)
Mission                                                                  MarketsThe companys ambition is to help          ...
Who are you?
This talk is about...    ... automatic tests... written by developers
Why should I test?
Why should I test JavaScript code?
Runtime environments for       JavaScript                       ...
In this talkIcon Set by Paul Irish (http://paulirish.com/2010/high-res-browser-icons/)
The example
Writing tests
„Classic style“ with    xUnit asserts„BDD style“ à la RSpec
Demo: BDD with Jasmine
Hello Jasmine!  expect(x).toEqual(y);    expect(x).toBe(y); expect(x).toBeDefined();expect(x).toBeUndefined(); expect(x).t...
Advanced concepts
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 ...
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 () {                 // ...
Function                    The spy should...spy.andCallThrough()        ... call the original functionspy.andReturn(argum...
Function                      Checks whether the spy...toHaveBeenCalled()            ... has been called                  ...
Asynchronous tests
Asynchronous testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");   ...
Asynchronous testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");   ...
Asynchronous testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");   ...
Asynchronous testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");   ...
Asynchronous testsit("should eventually set opacity to 1", function() {    var element = document.createElement("div");   ...
UI tests with Jasmine UI
Jasmine UI  Extension of JS test framework JasmineAllows to load, instrument and test a webapp                in the brows...
Analyse             HTML Session Storage   Show            specs                                    results    Scripts:   ...
<html><body><div id="hello">Hello World!</div><button id="fadein">Fade in</button></body></html>                          ...
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 ()...
InstrumentdescribeUi("index", "/js-fadein/index.html", function () {      beforeLoad(function() {          mockBackend(); ...
InstrumentdescribeUi("index", "/js-fadein/index.html", function () {      beforeLoad(function() {          mockBackend(); ...
InstrumentdescribeUi("index", "/js-fadein/index.html", function () {      beforeLoad(function() {          mockBackend(); ...
Jasmine UI: Roadmap Support other test runners     (e.g. testacular)Support other test frameworks         (e.g. QUnit)
Present: describeUidescribeUi(todo, /todo-mobile, function() {    // ...});
Future: loadUijasmineui.loadUi(/todo-mobile, function() {      // Jasmine specs      describe(todo, function() {          ...
Automated test execution
Pro               Examples                Browser from       QUnit Testing in                 production        YUI Testth...
Remote browser control
JsTestDriverhttp://code.google.com/p/js-test-driver/
Demo: JsTestDriver
ConclusionThere are a lot of tools for testing JavaScript                     code.               Test your code!    Espec...
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/)                              ...
Thanks for listening!       @tigbro
www.opitz-consulting.com/go_mobile
Test Driven JavaScript Development – WebTechConference 2012
Upcoming SlideShare
Loading in...5
×

Test Driven JavaScript Development – WebTechConference 2012

2,439

Published on

http://www.opitz-consulting.com/go/3-4-898

JavaScript is both a very dynamic language and interpreted slightly differently in every browser. Therefore, automatic tests are especially valueable for JavaScript. This talk shows how to develop cross browser tests for JavaScript. We discuss isolated unit tests and especially how to test the user inteface, which uses asynchronous functionalities like AJAX, animations, etc.

OPITZ CONSULTING JavaScript Expert Tobias Bosch presented this session at WebTechConference on 17/10/2012 in Mainz, Germany.

--
About us

OPITZ CONSULTING is a leading project specialist for custom-build applications and individual business intelligence solutions in the German market. The company's ambition is to help organizations to be better than their competitors. To achieve this OPITZ CONSULTING analyses the individual competitive edge the customer has, optimizes business processes for process automation and IT-support, chooses and designs appropriate system architectures, develops and implements solutions and guarantees a 24/7 support and application maintenance. To ensure the necessary skill and qualification OPITZ CONSULTING has established a training center for customers and the internal staff.

Since 1990 over 600 customers have a long lasting and successful business relationship with OPITZ CONSULTING. Over 2/3 of the German stock index (DAX) companies rely on services from the 400+ OPITZ CONSULTING consultants. OPITZ CONSULTING maintains offices in Bad Homburg, Berlin, Essen, Gummersbach, Hamburg, Munich, Nuremberg and Kraków (Poland).

About us: http://www.opitz-consulting.com/en/about_us
Services: http://www.opitz-consulting.com/en/leistungsangebot
Career: http://www.opitz-consulting.com/en/career

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

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

No notes for slide

Transcript of "Test Driven JavaScript Development – WebTechConference 2012"

  1. 1. Test Driven JavaScript DevelopmentTobias BoschOPITZ CONSULTING Deutschland GmbH
  2. 2. Who am I?tobias.bosch@opitz-consulting.com (@tigbro)
  3. 3. Mission MarketsThe companys ambition is to help  Branchspreadingorganizations to be better than their  Over 600 customerscompetitors. 29% Trade / Logistics /Our services take place in partnership and 29% Supplier Industry / Services /are aimed at a co-operation of many years. Telecommunications 42% Public Clients / Banks and Insurance Associations and FederationsPortfolio Basic Data Business IT Alignment  Founded in 1990 Business Information Management  400 employees Business Process Management  8 offices Application Development SOA and System Integration IT Infrastructure Management <Präsentationstitel – bitte im Folienmaster ändern> © OPITZ CONSULTING GmbH 2011 Seite 3
  4. 4. Who are you?
  5. 5. This talk is about... ... automatic tests... written by developers
  6. 6. Why should I test?
  7. 7. Why should I test JavaScript code?
  8. 8. Runtime environments for JavaScript ...
  9. 9. In this talkIcon Set by Paul Irish (http://paulirish.com/2010/high-res-browser-icons/)
  10. 10. The example
  11. 11. Writing tests
  12. 12. „Classic style“ with xUnit asserts„BDD style“ à la RSpec
  13. 13. Demo: BDD with Jasmine
  14. 14. Hello Jasmine! expect(x).toEqual(y); expect(x).toBe(y); expect(x).toBeDefined();expect(x).toBeUndefined(); expect(x).toBeTruthy(); expect(x).toBeFalsy(); ...
  15. 15. Advanced concepts
  16. 16. Spies
  17. 17. 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); });});
  18. 18. 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); });});
  19. 19. 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); });});
  20. 20. 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); });});
  21. 21. 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);of element to opacity // set opacity var mostRecentCall = util.opacity.mostRecentCall; util.opacity = function (element, opacity) { ... expect(mostRecentCall.args[0]).toBe(element); }; expect(mostRecentCall.args[1]).toEqual(1); });});
  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"); 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); });});
  24. 24. 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); });});
  25. 25. Spiesdescribe("execute fadein", function() { it("should eventually set opacity to 1", function () { // set opacity of element to opacity util.opacity = function (element, opacity) { 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); });});
  26. 26. Function The spy should...spy.andCallThrough() ... call the original functionspy.andReturn(argument) ... return the given argumentspy.andThrow(exception) ... throw the given exceptionspy.andCallFake(function) ... call the given function Functions of spies
  27. 27. Function Checks whether the spy...toHaveBeenCalled() ... has been called ... has been called with the giventoHaveBeenCalledWith(args) arguments Matcher for spiesFunction Descriptionspy.callCount Number of callsspy.argsForCall[i] Arguments of the i-th callspy.mostRecentCall.args Arguments of the last call Properties of spies
  28. 28. Asynchronous tests
  29. 29. Asynchronous 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); });});
  30. 30. Asynchronous 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); });});
  31. 31. Asynchronous 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); });});
  32. 32. Asynchronous 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) }); ...}); };
  33. 33. Asynchronous 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. UI tests with Jasmine UI
  35. 35. Jasmine UI Extension of JS test framework JasmineAllows to load, instrument and test a webapp in the browser Supports testing asynchronous behaviour
  36. 36. Analyse HTML Session Storage Show specs results Scripts: Load Scripts: appjasmine-ui.js jasmine-ui.jsjasmine-html.js jasmine-html.js"uiSpec.js" Collect "uiSpec.js" resultsUiSpecRunner.html UiSpecRunner.html Scripts: "app.js" Execute "uiSpec.js" specs index.html
  37. 37. <html><body><div id="hello">Hello World!</div><button id="fadein">Fade in</button></body></html> UI tests with Jasmine-UI
  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 tests with 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 tests with 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 tests with 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 tests with 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 tests with 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 tests with Jasmine-UI
  44. 44. InstrumentdescribeUi("index", "/js-fadein/index.html", function () { beforeLoad(function() { mockBackend(); }); ...});
  45. 45. InstrumentdescribeUi("index", "/js-fadein/index.html", function () { beforeLoad(function() { mockBackend(); }); ...});
  46. 46. InstrumentdescribeUi("index", "/js-fadein/index.html", function () { beforeLoad(function() { mockBackend(); }); ...});
  47. 47. Jasmine UI: Roadmap Support other test runners (e.g. testacular)Support other test frameworks (e.g. QUnit)
  48. 48. Present: describeUidescribeUi(todo, /todo-mobile, function() { // ...});
  49. 49. Future: loadUijasmineui.loadUi(/todo-mobile, function() { // Jasmine specs describe(todo, function() { it(should do smth, function() { ... }); }); // QUnit tests module("todo"); test("should do smth", function() { // ... });});
  50. 50. Automated test execution
  51. 51. Pro Examples Browser from QUnit Testing in production YUI Testthe browser environment Jasmine Envjs Easier to automate Headless PhantomJS Easier to embed browser Zombie.js into CI HtmlUnit
  52. 52. Remote browser control
  53. 53. JsTestDriverhttp://code.google.com/p/js-test-driver/
  54. 54. Demo: JsTestDriver
  55. 55. ConclusionThere are a lot of tools for testing JavaScript code. Test your code! Especially test your JavaScript code! You have no excuse ...
  56. 56. 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/
  57. 57. 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/)
  58. 58. 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/)
  59. 59. Thanks for listening! @tigbro
  60. 60. www.opitz-consulting.com/go_mobile

×