Practical guide
  to unit testing

Krzysztof Szafranek   meet.js summit 2012

                                            1
[ˈkʂɨʂtɔf ʂafranˈɛk]

    Roche front-end unit leader
    Nokia front-end architect
    wooga game developer

                                          2

Everything front-end.
Currently HTML5 game developer @ wooga.
in
                                                pr
                                                  ac
                                                    tic
    unit test




                                                       e™
     a function created to test
     other function




                                                            3

This is what it comes down to in JavaScript.
unit
        testing?



                                                   4

Unit testing is very much like regular exercise:
everybody knows it’s good, but few people do it.
I don’t know what
                            are unit tests        My code doesn’t
                                                       need tests
                                            3%
                                                 5%




                                                      I don’t write tests,
                     47%                               but I would like to

           I write tests                              45%




                                                                             5

The results of the poll I ran on my blog.
I got 60 responses.
I don’t know what
                            are unit tests        My code doesn’t
                                                       need tests
                                            3%
                                                 5%




                                                      I don’t write tests,
                     47%                               but I would like to

           I write tests                              45%




                                                                             5

The results of the poll I ran on my blog.
I got 60 responses.
tests increase
   confidence
                                                                                 6

It’s easier to change code knowing that tests will show places affected by the
change.
tests encourage
      good design

                                                                               7

Tests force your methods to be short, simple and with very few dependencies.
You end up in the code that’s not only less buggy, but also more readable.
collective
          ownership
                                                                                 8

No, it’s not communism. It means that the code is guarded from harm by tests.
Team members can confidently modify the code they didn’t write, as long as they
ensure that test still pass.
one click to
            test them all
                                                                                  9

With test runner all your tests can be run automatically at the same time in as
many browsers you want.
the
      “We don’t have
       time for that!”
             argument
                                                10

The most common excuse for not writing tests.
cumulative functionality


                                                                       si gn
                                                                    d e
                                                             o od
                                                         g

                                                                no design
                             design payoff line




                                                  time
                                                                               11

The graph comes from Martin Fowler’s article: http://martinfowler.com/bliki/
DesignStaminaHypothesis.html
It applies very much to unit testing.
cumulative functionality


                                                                       si gn
                                                                    d e
                                                             o od
                                                         g

                                                                no design
                             design payoff line




                                                  time
                                                                               11

The graph comes from Martin Fowler’s article: http://martinfowler.com/bliki/
DesignStaminaHypothesis.html
It applies very much to unit testing.
cumulative functionality


                                                                       si gn
                                                                    d e
                                                             o od
                                                         g

                                                                no design
                             design payoff line




                                                  time
                                                                               11

The graph comes from Martin Fowler’s article: http://martinfowler.com/bliki/
DesignStaminaHypothesis.html
It applies very much to unit testing.
“it's much
                                                lower than
                                               most people
                                             think: usually
                                                 weeks not
                                                  months.”


                                                        Martin Fowler
                                                                                     12

From my own experience, if you work on the project for longer than one man-
month, the tests are starting to pay off for themselves in better quality and less
time spent on finding and fixing bugs.
the how
          13
1. test




                                                  TD
                                                     D
   2. minimum code
      that works
   3. refactor
   4. repeat
                                                           14


This behavior is Test Driven Development. Some people prefer
writing implementation before tests. That can work too.
tools
        15
buster.js
       test framework
               +
         test runner
                                                             16


New, but already powerful framework by Christian Johansen:
- extensible API with optional BDD syntax
- easy mocking, also for server connections
- easy to automate
- node and browser tests
no
                                             de
       buster.js                                   .js
                                                        !

       test framework
               +
         test runner
                                                             16


New, but already powerful framework by Christian Johansen:
- extensible API with optional BDD syntax
- easy mocking, also for server connections
- easy to automate
- node and browser tests
config




    sources            client        server


                                                   browsers


                                                                17


The diagram is based on: http://code.google.com/p/js-test-
driver/
Buster implements most of the features of js-test-driver, and
more.
function async() {
        window.globalVar = false;
        setTimeout(function() {
            window.globalVar = true;
        }, 100);
    }




    buster.testCase("asynchronous tests", {
        "test async changes global variable": function() {
            var clock = this.useFakeTimers();
            async();
            clock.tick(200);
            buster.assert.equals(window.globalVar, true);
            clock.restore();
        }
    });



                                                                18


One of my favourite buster features: making asynchronous
code with setTimeout running instantly. It keeps your tests fast.
UnitTesting       TestCase               Test.More
       TestIt                                      screw-unit
                                      JSUnit
                          QUnit
  jsUnitTest
                  Jasmine
                         Test.Simple Crosscheck
                                                Nodeunit
          YUITest
    DOH              JSTest
                                 JSpec
                                         RhinoUnit
                  J3Unit
      Sinon.js
                            FireUnit     js-test-driver
             JSNUnit
       JSSpec                         Vows        SOAtest
                        Tyrtle

                                     jsUnity              JSTest.NET
          JasUnit
                                                                              19

There are many JavaScript unit testing frameworks and the above list (from
http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#JavaScript) is
already incomplete.
tools are
                secondary

                                                                                     20

If you find a different framework that fits your needs, that’s fine. Actually writing
tests is more important than a choice of a particular framework.
demo time!
                                                                                21

Demonstration of buster.js with a simple test run in two desktop browsers and
iOS simulator.
1. test
2. minimum code
   that works
3. refactor
4. repeat
                  22
Practical guide
     to unit testing

                                                  23

Thing’s I learned about JS unit testing myself.
e
                t ic
          a c
       p r
  in


                    test what
                     matters
                                                                         24

Don’t test getters and setters, but methods that actually do something
e
                t ic
          a c
       p r

                      test
  in



                    your own
                     system
                                                                                25

Don’t test browsers, network connections and other external systems. If your unit
tests are sending requests over network, you’re doing something wrong.
e
                t ic
          a c
       p r
  in


    keep your tests
         fast

                        26

- What is “fast”...?
- 1 second is fast.
e
                t ic
          a c
       p r
  in


                        write tests
                        as you go

                                                                                  27

I don’t belive in large retrospective refactorings.
If you have a lot of untested code:
- Write test BEFORE when you have to fix a bug. It will ensure the bug will not
re-appear in the future.
- Write tests for all new code.
- Don’t refactor without writing tests first. Otherwise it’s running around with
scissors, not refactoring.
e
                t ic
          a c
       p r
  in



                   automate

                                                                            28

Early error detection for free.
Use continuous integration software (Jenkins, Hudson, Cruise Control...).
e
                t ic
          a c
       p r
  in



             expect tests

                                                                                   29

Tests should be part of your definition of done. A feature without tests can’t be
considered complete.
I challenge
                                 you!
                                                                                     30

Start writing tests the next time you write code after watching this presentation!
krzysztof@szafranek.net
         (name)




        Thank you!

                          31
krzysztof@szafranek.net
       (contact email)




         Thank you!

                          32
krzysztof@szafranek.net
         (twitter)




        Thank you!

                          33
krzysztof@szafranek.net
        (website)




        Thank you!

                          34
photo credits:
pragdave       edtechie99
varun suresh   cyberpenguin
rwoan


                              35

Practical Guide to Unit Testing

  • 1.
    Practical guide to unit testing Krzysztof Szafranek meet.js summit 2012 1
  • 2.
    [ˈkʂɨʂtɔf ʂafranˈɛk] Roche front-end unit leader Nokia front-end architect wooga game developer 2 Everything front-end. Currently HTML5 game developer @ wooga.
  • 3.
    in pr ac tic unit test e™ a function created to test other function 3 This is what it comes down to in JavaScript.
  • 4.
    unit testing? 4 Unit testing is very much like regular exercise: everybody knows it’s good, but few people do it.
  • 5.
    I don’t knowwhat are unit tests My code doesn’t need tests 3% 5% I don’t write tests, 47% but I would like to I write tests 45% 5 The results of the poll I ran on my blog. I got 60 responses.
  • 6.
    I don’t knowwhat are unit tests My code doesn’t need tests 3% 5% I don’t write tests, 47% but I would like to I write tests 45% 5 The results of the poll I ran on my blog. I got 60 responses.
  • 7.
    tests increase confidence 6 It’s easier to change code knowing that tests will show places affected by the change.
  • 8.
    tests encourage good design 7 Tests force your methods to be short, simple and with very few dependencies. You end up in the code that’s not only less buggy, but also more readable.
  • 9.
    collective ownership 8 No, it’s not communism. It means that the code is guarded from harm by tests. Team members can confidently modify the code they didn’t write, as long as they ensure that test still pass.
  • 10.
    one click to test them all 9 With test runner all your tests can be run automatically at the same time in as many browsers you want.
  • 11.
    the “We don’t have time for that!” argument 10 The most common excuse for not writing tests.
  • 12.
    cumulative functionality si gn d e o od g no design design payoff line time 11 The graph comes from Martin Fowler’s article: http://martinfowler.com/bliki/ DesignStaminaHypothesis.html It applies very much to unit testing.
  • 13.
    cumulative functionality si gn d e o od g no design design payoff line time 11 The graph comes from Martin Fowler’s article: http://martinfowler.com/bliki/ DesignStaminaHypothesis.html It applies very much to unit testing.
  • 14.
    cumulative functionality si gn d e o od g no design design payoff line time 11 The graph comes from Martin Fowler’s article: http://martinfowler.com/bliki/ DesignStaminaHypothesis.html It applies very much to unit testing.
  • 15.
    “it's much lower than most people think: usually weeks not months.” Martin Fowler 12 From my own experience, if you work on the project for longer than one man- month, the tests are starting to pay off for themselves in better quality and less time spent on finding and fixing bugs.
  • 16.
  • 17.
    1. test TD D 2. minimum code that works 3. refactor 4. repeat 14 This behavior is Test Driven Development. Some people prefer writing implementation before tests. That can work too.
  • 18.
  • 19.
    buster.js test framework + test runner 16 New, but already powerful framework by Christian Johansen: - extensible API with optional BDD syntax - easy mocking, also for server connections - easy to automate - node and browser tests
  • 20.
    no de buster.js .js ! test framework + test runner 16 New, but already powerful framework by Christian Johansen: - extensible API with optional BDD syntax - easy mocking, also for server connections - easy to automate - node and browser tests
  • 21.
    config sources client server browsers 17 The diagram is based on: http://code.google.com/p/js-test- driver/ Buster implements most of the features of js-test-driver, and more.
  • 22.
    function async() { window.globalVar = false; setTimeout(function() { window.globalVar = true; }, 100); } buster.testCase("asynchronous tests", { "test async changes global variable": function() { var clock = this.useFakeTimers(); async(); clock.tick(200); buster.assert.equals(window.globalVar, true); clock.restore(); } }); 18 One of my favourite buster features: making asynchronous code with setTimeout running instantly. It keeps your tests fast.
  • 23.
    UnitTesting TestCase Test.More TestIt screw-unit JSUnit QUnit jsUnitTest Jasmine Test.Simple Crosscheck Nodeunit YUITest DOH JSTest JSpec RhinoUnit J3Unit Sinon.js FireUnit js-test-driver JSNUnit JSSpec Vows SOAtest Tyrtle jsUnity JSTest.NET JasUnit 19 There are many JavaScript unit testing frameworks and the above list (from http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#JavaScript) is already incomplete.
  • 24.
    tools are secondary 20 If you find a different framework that fits your needs, that’s fine. Actually writing tests is more important than a choice of a particular framework.
  • 25.
    demo time! 21 Demonstration of buster.js with a simple test run in two desktop browsers and iOS simulator.
  • 26.
    1. test 2. minimumcode that works 3. refactor 4. repeat 22
  • 27.
    Practical guide to unit testing 23 Thing’s I learned about JS unit testing myself.
  • 28.
    e t ic a c p r in test what matters 24 Don’t test getters and setters, but methods that actually do something
  • 29.
    e t ic a c p r test in your own system 25 Don’t test browsers, network connections and other external systems. If your unit tests are sending requests over network, you’re doing something wrong.
  • 30.
    e t ic a c p r in keep your tests fast 26 - What is “fast”...? - 1 second is fast.
  • 31.
    e t ic a c p r in write tests as you go 27 I don’t belive in large retrospective refactorings. If you have a lot of untested code: - Write test BEFORE when you have to fix a bug. It will ensure the bug will not re-appear in the future. - Write tests for all new code. - Don’t refactor without writing tests first. Otherwise it’s running around with scissors, not refactoring.
  • 32.
    e t ic a c p r in automate 28 Early error detection for free. Use continuous integration software (Jenkins, Hudson, Cruise Control...).
  • 33.
    e t ic a c p r in expect tests 29 Tests should be part of your definition of done. A feature without tests can’t be considered complete.
  • 34.
    I challenge you! 30 Start writing tests the next time you write code after watching this presentation!
  • 35.
    krzysztof@szafranek.net (name) Thank you! 31
  • 36.
    krzysztof@szafranek.net (contact email) Thank you! 32
  • 37.
    krzysztof@szafranek.net (twitter) Thank you! 33
  • 38.
    krzysztof@szafranek.net (website) Thank you! 34
  • 39.
    photo credits: pragdave edtechie99 varun suresh cyberpenguin rwoan 35