Skip to main content
S(p)exy testing in Coffeescript and Node.js




 Aaron Murray                Nicholas Vaidyanathan
 @WeAreFractal                   @SWVisionary
We’re glad you’re here!




But you obviously care about tests, so
 let’s talk about some terminology…
TDD, ATDD, BDD, DDD?
                          That’s a lot of DD’s

• TDD = Test Driven Development – Development Methodology, write tests
  first, test using xUnit – make sure the code works

• ATDD = Acceptance Test Driven Development – business-readable, Team-
  driven, tests owned by client – make sure the features are correct

• BDD = Behavior Driven Development – Team-driven, “Should”, “Given,
  When, Then” – extends TDD and incorporates ATDD

• DDD = Domain Driven Design – outlines the idea of the Ubiquitous
  Language used between non-technical stakeholders and developers
Wait, DDD? Why?
• What does DDD have to do with BDD?
• Proper architecture helps you
  – set up smallest possible services
  – Focus on nouns and verbs
  – Describes behavior, which drives BDD process
• Testing IS Design!!!!

• GOOD ARCHITECTURE IS PIVOTAL TO
  SUCCESSFUL BDD!
In the beginning, there was TDD
• Test Driven Development
  – Rediscovered by Kent Beck @kentbeck
• Simple Process
  – Test
  – Code
  – Refactor
Tests looked like this




• http://junit.sourceforge.net/doc/cookbook/cook
  book.htm
Then we came to ATDD
                      • TDD is a programming practice, not
                        a testing technique.
                      • Acceptance Test Driven
                        Development (ATDD) also involves
                        creating tests before code
                      • tests represent expectations of
                        behavior the software should have.
                      • team creates one or more
                        acceptance-level tests for a feature
                        before beginning work on it.
                      • team discusses tests and captures
                        them when working with the
                        business stakeholder(s) to
                        understand a story on the backlog.



• http://testobsessed.com/wp-
  content/uploads/2011/04/atddexample.pdf
And BDD
• Evolved out of established agile practices and is designed to
  make them more accessible and effective for teams new to
  agile software delivery.
• Premises
   –   Test method names should be sentences
   –   A simple sentence template keeps test methods focused
   –   An expressive test name is helpful when a test fails
   –   “Behaviour” is a more useful word than “test”
   –   Determine the next most important behaviour
   –   Requirements are behaviour,too
   –   BDD provides a “ubiquitous language” for analysis
   –   Acceptance criteria should be executable
• http://dannorth.net/introducing-bdd/
BDD Breakdown
Fundamentally Two Types of BDD Tools

Business-readable output
    –   Replacement/Extension for TDD at the Unit-testing level
    –   Artifacts owned by developers (code)
    –   Provides other stakeholders with reports after developers have done the work
    –   Gspec, Spock, EasyB


Business-readable input
    –   Based on Acceptance Testing – coarse-grained features
    –   Artifacts owned by client
    –   Stakeholder involvement before developers have done any work
    –   Cucumber, FitNesse


    Not exclusive – can and probably need to be combined
EasyB
                                   business-readable output

input                                                output
scenario "Two amounts with the same currencies are   2 scenarios executed successfully.
       added", {
  given "Two different amounts with the same              Story: money
       currencies", {
    money1 = new Money(12, "CHF")                         scenario Two amounts with the same
    money2 = new Money(14, "CHF")
                                                        currencies are added
                                                           given Two different amounts with
    expected = new Money(26, "CHF")                     the same currencies
  }                                                        when Add given amounts
  when "Add given amounts" , {                             then New amount is sum of two
    result = money1.add(money2)                         given ones
  }                                                       scenario Two amounts with different
  then "New amount is sum of two given ones", {         currencies are added
    result.equals(expected).shouldBe true                  given Two amounts with different
  }                                                     currencies
                                                           when Add given amounts
}
                                                           then Operation should fail
…
<<truncated>>
Step 1: write your feature
                        Addition.feature
Feature: Addition
  In order to avoid silly mistakes
  As a math idiot
  I want to be told the sum of two numbers

 Scenario: Add two numbers
   Given I have entered <input_1> into the calculator
   And I have entered <input_2> into the calculator
   When I press <button>
   Then the result should be <output> on the screen

 Examples:
   | input_1   |   input_2   |   button   |   output   |
   | 20        |   30        |   add      |   50       |
   | 2         |   5         |   add      |   7        |
   | 0         |   40        |   add      |   40       |
Step 2: step definition
                     CalculatorSteps.groovy
this.metaClass.mixin(cuke4duke.GroovyDsl)

Before() {
    calc = new Calculator()
}

Given(~"I have entered (d+) into the calculator") { int n ->
    calc.push n
}

When(~"I press (w+)") {op ->
    result = calc.send(op)
}

Then(~"the result should be (.*) on the screen") { int r ->
    assert r == result
}
Step 4: write code to make it pass
                          Calculator.groovy
class Calculator {
    def numbers = []

    void push(number) {
        numbers << number
    }

    def send(operation) {
        def result
        switch (operation) {
            case "add":
                result = add()
        }
        numbers.clear()
        result
    }

    private def add() {
        numbers.sum()
    }
}
BDD in Java/Coffeescript and Node
• Best available frameworks
  – Jasmine
  – Vows
• Comparison
  – http://stackoverflow.com/questions/4115492/jav
    ascript-bdd-vows-kyuri-vs-jasmine
• So…
Introducing
•   Built in Node.js natively
•   Written in CoffeeScript
•   Modular, clean architecture
•   Designed to dramatically simplify the BDD process
•   Provides an annotation based mechanism for
    defining your tests
Example spec
Benefits
• Clean syntax
• Doesn’t pollute global namespace
• Flexibility

• Give it a try
   – https://github.com/wearefractal/spex
• LIVE DEMO