SlideShare a Scribd company logo
3 WAYS TO TEST YOUR
COLDFUSION API
Gavin Pickin
cf.Objective() 2017
Agenda
● Who Am I?
● State of the Room?
● CF API
● Ways to test your API?
● Overview of Testing Tools
● Using Testing in your Workflow
● Installing Jasmine
● Installing Testbox
● Live Demo
Who am I?
Gavin Pickin – developing Web Apps since late 90s
● Software Consultant for Ortus Solutions
● ContentBox Evangelist
What else do you need to know?
● Blog - http://www.gpickin.com
● Twitter – http://twitter.com/gpickin
● Github - https://github.com/gpickin
Let’s get on with the show.
State of the Room
● A few questions for you guys
● If you have arms, use them.
APIs in CFML
Most CF Apps are moving towards providing an API for multiple consumers
CF has many REST API Solutions and even more with CF 2016
● Built in CF
● Built in Railo/Lucee
● Coldbox API
● Taffy
Ways to Test your Code
● Click around in the browser yourself
● Setup Selenium / Web Driver to
click around for you
● Structured Programmatic Tests
Types of Testing
● Black/White Box
● Unit Testing
● Integration Testing
● Functional Tests
● System Tests
● End to End Tests
● Sanity Testing
● Regression Test
● Acceptance Tests
● Load Testing
● Stress Test
● Performance Tests
● Usability Tests
● + More
Integration Testing
● Integration Tests several of the pieces together
● Most of the types of tests are variations of an Integration
Test
● Can include mocks but can full end to end tests including
DB / APIs
Unit Testing
“unit testing is a software verification and validation method in
which a programmer tests if individual units of source code
are fit for use. A unit is the smallest testable part of an
application”
- wikipedia
Unit Testing can...
● Can improve code quality -> quick error discovery
● Code confidence via immediate verification
● Can expose high coupling
● Will encourage refactoring to produce > testable code
● Remember: Testing is all about behavior and expectations
Styles – TDD vs BDD
● TDD = Test Driven Development
○ Write Tests
○ Run them and they Fail
○ Write Functions to Fulfill the Tests
○ Tests should pass
○ Refactor in confidence
Test focus on Functionality
Styles - TDD vs BDD
● BDD = Behavior Driven Development
Actually similar to TDD except:
● Focuses on Behavior and Specifications
● Specs (tests) are fluent and readable
● Readability makes them great for all levels of testing in the
organization
Hard to find TDD examples in JS that are not using BDD describe and it
blocks
TDD Example
Test( ‘Email address must not be blank’, function(){
notEqual(email, “”, "failed");
});
BDD Example
Describe( ‘Email Address’, function(){
It(‘should not be blank’, function(){
expect(email).not.toBe(“”);
});
});
Matchers
expect(true).toBe(true);
expect(true).toBe(true);
expect(true).toBe(true);
expect(true).toBe(true);
Matchers
expect(true).not.toBe(true);
expect(true).not.toBe(true);
expect(true).not.toBe(true);
expect(true).not.toBe(true);
expect(true).not.toBe(true);
Matcher Samples
expect(true).toBe(true);
expect(a).not.toBe(null);
expect(a).toEqual(12);
expect(message).toMatch(/bar/);
expect(message).toMatch("bar");
expect(message).not.toMatch(/quux/);
expect(a.foo).toBeDefined();
expect(a.bar).not.toBeDefined();
Different Testing
Environments?
NodeJS - CLI In the Browser
CF Testing Tools
* MxUnit was the standard
* TestBox is the new standard
Other options
TestBox
TestBox is a next generation testing framework for ColdFusion
(CFML) that is based on BDD (Behavior Driven Development)
for providing a clean obvious syntax for writing tests.
It contains not only a testing framework, runner, assertions
and expectations library but also ships with MockBox, A
Mocking & Stubbing Framework,.
It also supports xUnit style of testing and MXUnit
compatibilities.
TestBox TDD Example
function testHelloWorld(){
          $assert.includes( helloWorld(), ”world" );
     }
TestBox BDD Example
describe("Hello world function", function() {
it(”contains the word world", function() {
expect(helloWorld()).toContain("world");
});
});
TestBox New BDD Example
feature( "Box Size", function(){
    describe( "In order to know what size box I need
              As a distribution manager
              I want to know the volume of the box", function(){
        scenario( "Get box volume", function(){
            given( "I have entered a width of 20
                And a height of 30
                And a depth of 40", function(){
                when( "I run the calculation", function(){
                      then( "the result should be 24000", function(){
JS Testing Tools
*There are a few choices
Main JS Testing Players
Jasmine, Mocha and QUnit
Jasmine
*Jasmine comes ready to go out of the box
*Fluent Syntax – BDD Style
*Includes lots of matchers
*Has spies included
*Very popular, lots of support
*Angular uses Jasmine with Karma (CLI)
*Headless running and plays well with CI servers
Jasmine - Cons
Async testing in 1.3 can be a headache
*Async testing in 2.0 is hard to find
blog posts on (I need to write one)
*Expects *spec.js suffix for test files
*This can be modified depending on
how you are running the tests
Jasmine – Sample Test
describe("Hello world function", function() {
it(”contains the word world", function() {
expect(helloWorld()).toContain("world");
});
});
Mocha
*Simple Setup
*Simple Async testing
*Works great with other Assertion libraries like Chai ( not
included )
*Solid Support with CI Servers, with Plugins for others
*Opinion says Mocha blazing the trail for new features
Mocha - Cons
*Requires other Libraries for key features
*No Assertion Library included
*No Mocking / Spied included
*Need to create the runner manually
*Newer to the game so not as popular or supported as
others but gaining traction.
Mocha – BDD Sample Test
var expect = require('chai').expect;
describe(’Hello World Function', function(){
it('should contain the word world', function(){
expect(helloWorld()).to.contain(’world');
})
})
QUnit
*The oldest of the main testing frameworks
*Is popular due to use in jQuery and age
*Ember’s default Unit testing Framework
QUnit - Cons
*Development slowed down since
2013 (but still under development)
*Syntax – No BDD style
*Assertion libraries – limited matchers
QUnit – Sample Test
QUnit.test( "ok test", function( assert ) {
assert.ok( true, "true succeeds" );
assert.ok( "non-empty", "non-empty string succeeds"
);
assert.ok( false, "false fails" );
assert.ok( 0, "0 fails" );
assert.ok( NaN, "NaN fails" );
assert.ok( "", "empty string fails" );
assert.ok( null, "null fails" );
assert.ok( undefined, "undefined fails" );
Spaghetti Javascript
Photo Credit – Kombination
http://www.kombination.co.za/wp-content/uploads/2012/10/baby_w_spaghetti_mess_4987941.jpg
Spaghetti Javascript Example
Spaghetti Javascript Example
Refactoring Spaghetti
*Things to refactor to make your code testable
*Code should not be one big chunk of Javascript in
onReady()
*Deep nested callbacks & Anon functions cannot
easily be singled out and tested
*Remove Tight Coupling – DOM access for example
Refactoring Spaghetti
*Lets look at some code
*This isn’t BEST PRACTICE, its BETTER PRACTICE than
you were doing
*Its not really refactoring if you don’t have tests, its
“moving code and asking for trouble”
Kev McCabe
Object Literals
var personObjLit = {
ssn: ’xxxxxxxx',
age: '35',
name: 'Gavin Pickin',
getAge: function(){
return this.age;
},
getName: function() {
return this.name;
}
};
Module Pattern
var personObjLit2 = function() {
ssn = ’xxxxxxx';
age = '35';
name = 'Gavin Pickin’;
return {
getAge: function(){
return age;
},
getName: function() {
return name;
}
};
};
Using Testing in your Workflow
*Using HTML Test Runners
*Keep a Browser open
*F5 refresh tests
Command Line Tests
*Run Jasmine – manual
*Run tests at the end of each section of work
*Run Grunt-Watch – automatic
*Runs Jasmine on every file change
*Grunt can run other tasks as well,
minification etc
Testing in your IDE
*Browser Views
*Eclipse allows you to open files in web view
– uses HTML Runner
*Run Jasmine / Grunt / Karma in IDE Console
*Fairly Easy to setup
*See Demo– Sublime Text 2 (if we have time)
Live Demo and Examples
*Install / Run Jasmine Standalone for Browser
*Install / Run Jasmine with NodeJs
*Install / Run Jasmine with Grunt Watch
*Install / Run Testbox in Browser
Install / Run Jasmine for In-Browser Testing
Download standalone package from Github (I have 2.1.3)
https://github.com/jasmine/jasmine/tree/master/dist
Unzip into your /tests folder
Run /tests/SpecRunner.html to see example tests
Standalone Jasmine
Installing Jasmine for in Browser Testing
http://www.testableapi.local.com:8504/tests/SpecRunner.html
SpecRunner Setup Jasmine Browser Test
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Jasmine Spec Runner v2.1.3</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.1.3/jasmine_favicon.png">
<link rel="stylesheet" href="lib/jasmine-2.1.3/jasmine.css”>
<script src="lib/jasmine-2.1.3/jasmine.js"></script>
<script src="lib/jasmine-2.1.3/jasmine-html.js"></script>
<script src="lib/jasmine-2.1.3/boot.js"></script>
<!-- include source files here... -->
<script src="../js/services/loginService.js"></script>
<!-- include spec files here... -->
<script src="spec/loginServiceSpec.js"></script>
</head>
<body>
</body>
Installing Jasmine with NodeJS
Assuming you have NodeJs Installed… install Jasmine
$ npm install jasmine
jasmine@2.2.1 node_modules/jasmine
├── exit@0.1.2
├── jasmine-core@2.2.0
└── glob@3.2.11 (inherits@2.0.1, minimatch@0.3.0)
Installing Jasmine with NodeJS
Once Jasmine is installed in your project
$ Jasmine init
Installing Jasmine with NodeJS
Edit Jasmine.json to update Locations for Spec Files and Helper Files
{
"spec_dir": "spec",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"helpers/**/*.js"
]
}
Running Jasmine Tests with NodeJS
$ Jasmine
Started
F
Failures:
1) A suite contains spec with an expectation
Message:
Expected true to be false.
Stack:
Error: Expected true to be false.
at Object.<anonymous>
(/Users/gavinpickin/Dropbox/Apps/testApp/www/spec/test_spec.js:3:1
8)
1 spec, 1 failure
Running Jasmine Tests with NodeJS
*Jasmine-Node is great for Node
*Jasmine Node doesn’t have a headless browser
*Hard to test Browser code
*So what should I use?
Installing Jasmine with Grunt Watcher
*Install Grunt
npm install grunt
*Install Grunt – Jasmine
npm install grunt-contrib-jasmine
*Install Grunt – Watch
npm install grunt-contrib-watch
Configuring Jasmine with Grunt Watcher
// gruntfile.js - https://gist.github.com/gpickin/1e1e7902d1d3676d23c5
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('node_modules/grunt/package.json'),
jasmine: {
all: {
src: ['js/*.js' ],
options: {
//'vendor': ['path/to/vendor/libs/*.js'],
'specs': ['specs/*.js' ], '--web-security': false
}
Configuring Jasmine with Grunt Watcher
// gruntfile.js part 2
watch: {
js: {
files: [
'js/*.js',
'specs/*.js',
],
tasks: ['jasmine:all']
}
}
Configuring Jasmine with Grunt Watcher
// gruntfile.js part 3
grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.loadNpmTasks('grunt-contrib-watch');
};
Example Jasmine Spec with Grunt Watcher
describe("Forgotten Password Form", function() {
it("should warn you if the email is invalid before making Ajax Call",
function() {
expect( isEmailInputInvalid('') ).toBe(true);
expect( isEmailInputInvalid('dddddddddd') ).toBe(true);
expect( isEmailInputInvalid('dddddd@') ).toBe(true);
expect( isEmailInputInvalid('dddddd@ddddd') ).toBe(true);
expect( isEmailInputInvalid('dddddd@ddddddd.') ).toBe(true);
expect( isEmailInputInvalid('dddddd@ddddddd.com') ).toBe(false);
Example Jasmine Spec with Grunt Watcher
describe("Login Form", function() {
it("should set status correct status message with successful Ajax
Response", function() {
spyOn( window, "setStatusMessage");
processLoginAjaxDone('{"RESULT":"200"}');
expect(setStatusMessage).toHaveBeenCalled();
expect(setStatusMessage).toHaveBeenCalledWith(
‘TARDIS Access Granted - Please wait for the Doctor to take you for
a spin');
});
Example Jasmine Spec with Grunt Watcher
describe("Login API", function() {
it("should return a failing Ajax Response", function() {
spyOn( window, "processLoginAjaxDone");
loginButtonEventHandlerProcess( 'gavin@gavin.co.nz', 'password');
expect(processLoginAjaxDone).toHaveBeenCalled();
expect(processLoginAjaxDone).toHaveBeenCalledWith(
‘{"RESULT":400}');
expect(processLoginAjaxFail).not.toHaveBeenCalled();
Whats wrong with that?
describe("Login API", function() {
it("should return a failing Ajax Response", function() {
spyOn( window, "processLoginAjaxDone");
loginButtonEventHandlerProcess( 'gavin@gavin.co.nz', 'password');
expect(processLoginAjaxDone).toHaveBeenCalled();
expect(processLoginAjaxDone).toHaveBeenCalledWith(
‘{"RESULT":400}');
expect(processLoginAjaxFail).not.toHaveBeenCalled();
});
Unit Tests and Async Calls
*You want Unit Tests to test the unit and not it’s
dependencies
*You want Unit Tests to run quick
*You should mock the API in the Ajax call
*But we want to test the API
*So essentially, we’re writing an integration test.
How to wait for Async
describe("Login API", function() {
beforeEach(function( done ) {
spyOn( window, "processLoginAjaxDone").and.callFake(
function(){ done(); });
spyOn( window, "processLoginAjaxFail").and.callFake(
function(){ done(); });
loginButtonEventHandlerProcess('gavin@gavin.co.nz', 'password');
});
it("should return a failing Ajax Response", function() { });
});
How to wait for Async
describe("Login API", function() {
beforeEach(function( done ) {
…
});
it("should return a failing Ajax Response", function() {
expect(processLoginAjaxDone).toHaveBeenCalled();
expect(processLoginAjaxDone).toHaveBeenCalledWith(
'{"RESULT":400}');
expect(processLoginAjaxFail).not.toHaveBeenCalled();
});
Running Jasmine with Grunt Watcher
Running Jasmine with Grunt Watcher
Installing Testbox
*Install Testbox – Easy Thanks to Commandbox
*box install testbox
*Next, decide how you want to run Testbox
Create a runner.cfm
*<cfsetting showDebugOutput="false">
*<!--- Executes all tests in the 'specs' folder with simple reporter by
default --->
*<cfparam name="url.reporter" default="simple">
*<cfparam name="url.directory" default="tests.specs">
*<cfparam name="url.recurse" default="true"
type="boolean">
*<cfparam name="url.bundles" default="">
*<cfparam name="url.labels" default="">
Create a Test Suite
// tests/specs/CFCTest.cfc
component extends="testbox.system.BaseSpec" {
function run() {
it( "will error with incorrect login", function(){
var oTest = new cfcs.userServiceRemote();
expect( oTest.login( 'gavin@gavin.com',
'topsecret').result ).toBe('400');
});
}
Create a 2nd
Test Suite
// tests/specs/APITest.cfc
component extends="testbox.system.BaseSpec" {
function run() {
describe("userService API Login", function(){
it( "will error with incorrect login", function(){
var email = "gavin@gavin.com";
var password = "topsecret”;
var result = "";
http
url="http://www.testableapi.local.com:8504/cfcs/userServiceRemote.cfc?method=log
in&email=#email#&password=#password#" result="result”;
expect( DeserializeJSON(result.filecontent).result ).toBe('400');
});
});
Running Testbox with runner.cfm
Running Testbox with Grunt Watch
*Install Testbox Runner – Thanks Sean Coyne
*npm install testbox-runner
*Install Grunt Shell
*npm install grunt-shell
*Add Grunt Configuration
Adding TextBox Config 1
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-shell');
grunt.initConfig({ … })
}
Adding TextBox Config 2
Watch: {
…
cfml: {
files: [ "cfcs/*.cfc"],
tasks: [ "testbox" ]
}
}
Adding TextBox Config 3
shell: {
testbox: {
command:
"./node_modules/testbox-runner/index.js
--colors --runner
http://www.testableapi.local.com:8504/tests/r
unner.cfm --directory /tests/specs --recurse
true”
Adding TextBox Config 4
grunt.registerTask("testbox", [ "shell:testbox" ]);
grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.loadNpmTasks('grunt-contrib-watch');
Adding TextBox Config 5
js: {
files: [
'js/*.js',
'specs/*.js',
"cfcs/*.cfc”
],
tasks: ['jasmine:all']
},
GruntFile.js Gists
Jasmine
https://gist.github.com/gpickin/1e1e7902d1d36
76d23c5
Jasmine + Testbox
https://gist.github.com/gpickin/9fc82df3667ee
b63c7e7
Testbox output with Grunt
Testbox Runner JSON
*Testbox has several runners, you have seen the HTML one, this
Runner uses the JSON runner and then formats it.
*http://www.testableapi.local.com:8504/tests/runner.cfm?rep
orter=JSON&directory=%2Ftests%2Fspecs&recurse=true
Running in Sublime Text 2
*Install PackageControl into Sublime Text
*Install Grunt from PackageControl
*https://packagecontrol.io/packages/Grunt
*Update Grunt Sublime Settings for paths
{
"exec_args": { "path": "/bin:/usr/bin:/usr/local/bin” }
}
*Then Command Shift P – grunt
Running in Sublime Text 2
3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION API

More Related Content

What's hot

Bolt chart
Bolt chart Bolt chart
Bolt chart
Jennifer Villalon
 
Introduction to common rail ( Bosch; Denso; Delphi; Vdo)
Introduction to common rail ( Bosch; Denso; Delphi; Vdo)Introduction to common rail ( Bosch; Denso; Delphi; Vdo)
Introduction to common rail ( Bosch; Denso; Delphi; Vdo)
Luca Nurchi
 
Tabela de carros
Tabela de carrosTabela de carros
Tabela de carros
Raimundo Araujo Araujo
 
96 blazer all wiring diagrams
96 blazer all wiring diagrams96 blazer all wiring diagrams
96 blazer all wiring diagrams
ssusera59534
 
Tabela de Aplicação NGK - 2013
Tabela de Aplicação NGK - 2013Tabela de Aplicação NGK - 2013
Tabela de Aplicação NGK - 2013
mapplemkt
 
Tabela lampada-ponto
Tabela lampada-pontoTabela lampada-ponto
Tabela lampada-ponto
Raimundo Araujo Araujo
 
Halderman ch075 lecture
Halderman ch075 lectureHalderman ch075 lecture
Halderman ch075 lecture
mcfalltj
 
Carburador webe esquema
Carburador webe esquemaCarburador webe esquema
Carburador webe esquema
smttorres
 
Tabela de pressão de combustivel
Tabela de pressão de combustivelTabela de pressão de combustivel
Tabela de pressão de combustivel
Sergio Favaro
 
Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças
Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças
Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças
Junior Iung
 
Tabela de sensor de massa de ar
Tabela de sensor de massa de arTabela de sensor de massa de ar
Tabela de sensor de massa de ar
Sergio Favaro
 
Haas centre prelucrare scolarizare romana
Haas centre prelucrare scolarizare romanaHaas centre prelucrare scolarizare romana
Haas centre prelucrare scolarizare romana
ClimenteAlin
 
Tabela de Regulagem de Carburadores Marca Brosol
Tabela de Regulagem de Carburadores Marca BrosolTabela de Regulagem de Carburadores Marca Brosol
Tabela de Regulagem de Carburadores Marca Brosol
Danilop
 
Catálogo geral 2015
Catálogo geral 2015Catálogo geral 2015
Catálogo geral 2015
lynx_dc
 
Manual de serviço cg125 today cg125 titan cg125 cargo (1994) mskch941 p inf...
Manual de serviço cg125 today cg125 titan cg125 cargo (1994)   mskch941 p inf...Manual de serviço cg125 today cg125 titan cg125 cargo (1994)   mskch941 p inf...
Manual de serviço cg125 today cg125 titan cg125 cargo (1994) mskch941 p inf...
Thiago Huari
 
Industry
IndustryIndustry
Industry
Craig Kielb
 
Plano de teste 096000 4820 Denso
Plano de teste 096000 4820 DensoPlano de teste 096000 4820 Denso
Plano de teste 096000 4820 Denso
Junior Iung
 
Como instalar un modulo de ford
Como instalar un modulo de fordComo instalar un modulo de ford
Como instalar un modulo de ford
Elektroeli Gas
 
Manual de serviço cb400 cabecote
Manual de serviço cb400 cabecoteManual de serviço cb400 cabecote
Manual de serviço cb400 cabecote
Thiago Huari
 

What's hot (20)

Bolt chart
Bolt chart Bolt chart
Bolt chart
 
Introduction to common rail ( Bosch; Denso; Delphi; Vdo)
Introduction to common rail ( Bosch; Denso; Delphi; Vdo)Introduction to common rail ( Bosch; Denso; Delphi; Vdo)
Introduction to common rail ( Bosch; Denso; Delphi; Vdo)
 
Tabela de carros
Tabela de carrosTabela de carros
Tabela de carros
 
96 blazer all wiring diagrams
96 blazer all wiring diagrams96 blazer all wiring diagrams
96 blazer all wiring diagrams
 
Tabela de Aplicação NGK - 2013
Tabela de Aplicação NGK - 2013Tabela de Aplicação NGK - 2013
Tabela de Aplicação NGK - 2013
 
Tabela lampada-ponto
Tabela lampada-pontoTabela lampada-ponto
Tabela lampada-ponto
 
Halderman ch075 lecture
Halderman ch075 lectureHalderman ch075 lecture
Halderman ch075 lecture
 
Carburador webe esquema
Carburador webe esquemaCarburador webe esquema
Carburador webe esquema
 
Tabela de pressão de combustivel
Tabela de pressão de combustivelTabela de pressão de combustivel
Tabela de pressão de combustivel
 
Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças
Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças
Bomba Stanadyne DB2635-5681 Plano de teste e explodido de peças
 
Tabela de sensor de massa de ar
Tabela de sensor de massa de arTabela de sensor de massa de ar
Tabela de sensor de massa de ar
 
Haas centre prelucrare scolarizare romana
Haas centre prelucrare scolarizare romanaHaas centre prelucrare scolarizare romana
Haas centre prelucrare scolarizare romana
 
Tabela de Regulagem de Carburadores Marca Brosol
Tabela de Regulagem de Carburadores Marca BrosolTabela de Regulagem de Carburadores Marca Brosol
Tabela de Regulagem de Carburadores Marca Brosol
 
Catálogo geral 2015
Catálogo geral 2015Catálogo geral 2015
Catálogo geral 2015
 
Manual de serviço cg125 today cg125 titan cg125 cargo (1994) mskch941 p inf...
Manual de serviço cg125 today cg125 titan cg125 cargo (1994)   mskch941 p inf...Manual de serviço cg125 today cg125 titan cg125 cargo (1994)   mskch941 p inf...
Manual de serviço cg125 today cg125 titan cg125 cargo (1994) mskch941 p inf...
 
Industry
IndustryIndustry
Industry
 
Plano de teste 096000 4820 Denso
Plano de teste 096000 4820 DensoPlano de teste 096000 4820 Denso
Plano de teste 096000 4820 Denso
 
Como instalar un modulo de ford
Como instalar un modulo de fordComo instalar un modulo de ford
Como instalar un modulo de ford
 
Airbus 380
Airbus 380Airbus 380
Airbus 380
 
Manual de serviço cb400 cabecote
Manual de serviço cb400 cabecoteManual de serviço cb400 cabecote
Manual de serviço cb400 cabecote
 

Similar to 3 WAYS TO TEST YOUR COLDFUSION API

3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
Ortus Solutions, Corp
 
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
Ortus Solutions, Corp
 
How do I write Testable Javascript so I can Test my CF API on Server and Client
How do I write Testable Javascript so I can Test my CF API on Server and ClientHow do I write Testable Javascript so I can Test my CF API on Server and Client
How do I write Testable Javascript so I can Test my CF API on Server and Client
Gavin Pickin
 
How to write Testable Javascript
How to write Testable JavascriptHow to write Testable Javascript
How to write Testable Javascript
ColdFusionConference
 
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
Gavin Pickin
 
How do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and ClientHow do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and Client
ColdFusionConference
 
BDD Testing and Automating from the trenches - Presented at Into The Box June...
BDD Testing and Automating from the trenches - Presented at Into The Box June...BDD Testing and Automating from the trenches - Presented at Into The Box June...
BDD Testing and Automating from the trenches - Presented at Into The Box June...
Gavin Pickin
 
ITB2016 -BDD testing and automation from the trenches
ITB2016 -BDD testing and automation from the trenchesITB2016 -BDD testing and automation from the trenches
ITB2016 -BDD testing and automation from the trenches
Ortus Solutions, Corp
 
2014 11 20 Drupal 7 -> 8 test migratie
2014 11 20 Drupal 7 -> 8 test migratie2014 11 20 Drupal 7 -> 8 test migratie
2014 11 20 Drupal 7 -> 8 test migratie
hcderaad
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha Touch
Mats Bryntse
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
Gil Fink
 
Java script unit testing
Java script unit testingJava script unit testing
Java script unit testing
Mats Bryntse
 
Behat Workshop at WeLovePHP
Behat Workshop at WeLovePHPBehat Workshop at WeLovePHP
Behat Workshop at WeLovePHP
Marcos Quesada
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
Hendrik Ebbers
 
Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Tdd is not about testing (OOP)
Tdd is not about testing (OOP)
Gianluca Padovani
 
A la découverte des google/test (aka gtest)
A la découverte des google/test (aka gtest)A la découverte des google/test (aka gtest)
A la découverte des google/test (aka gtest)
Thierry Gayet
 
Android develop guideline
Android develop guidelineAndroid develop guideline
Android develop guideline
Kan-Han (John) Lu
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
Seb Rose
 
Testing in Craft CMS
Testing in Craft CMSTesting in Craft CMS
Testing in Craft CMS
JustinHolt20
 

Similar to 3 WAYS TO TEST YOUR COLDFUSION API (20)

3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
 
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
 
How do I write Testable Javascript so I can Test my CF API on Server and Client
How do I write Testable Javascript so I can Test my CF API on Server and ClientHow do I write Testable Javascript so I can Test my CF API on Server and Client
How do I write Testable Javascript so I can Test my CF API on Server and Client
 
How to write Testable Javascript
How to write Testable JavascriptHow to write Testable Javascript
How to write Testable Javascript
 
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
 
How do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and ClientHow do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and Client
 
BDD Testing and Automating from the trenches - Presented at Into The Box June...
BDD Testing and Automating from the trenches - Presented at Into The Box June...BDD Testing and Automating from the trenches - Presented at Into The Box June...
BDD Testing and Automating from the trenches - Presented at Into The Box June...
 
ITB2016 -BDD testing and automation from the trenches
ITB2016 -BDD testing and automation from the trenchesITB2016 -BDD testing and automation from the trenches
ITB2016 -BDD testing and automation from the trenches
 
2014 11 20 Drupal 7 -> 8 test migratie
2014 11 20 Drupal 7 -> 8 test migratie2014 11 20 Drupal 7 -> 8 test migratie
2014 11 20 Drupal 7 -> 8 test migratie
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha Touch
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
 
Java script unit testing
Java script unit testingJava script unit testing
Java script unit testing
 
Behat Workshop at WeLovePHP
Behat Workshop at WeLovePHPBehat Workshop at WeLovePHP
Behat Workshop at WeLovePHP
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
 
Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Tdd is not about testing (OOP)
Tdd is not about testing (OOP)
 
A la découverte des google/test (aka gtest)
A la découverte des google/test (aka gtest)A la découverte des google/test (aka gtest)
A la découverte des google/test (aka gtest)
 
Android develop guideline
Android develop guidelineAndroid develop guideline
Android develop guideline
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
 
Testing in Craft CMS
Testing in Craft CMSTesting in Craft CMS
Testing in Craft CMS
 

More from Gavin Pickin

Itb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin PickinItb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin Pickin
Gavin Pickin
 
Containerizing ContentBox CMS
Containerizing ContentBox CMSContainerizing ContentBox CMS
Containerizing ContentBox CMS
Gavin Pickin
 
ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...
ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...
ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...
Gavin Pickin
 
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEAN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
Gavin Pickin
 
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Gavin Pickin
 
Just Mock It - Mocks and Stubs
Just Mock It - Mocks and StubsJust Mock It - Mocks and Stubs
Just Mock It - Mocks and Stubs
Gavin Pickin
 
How do I write Testable Javascript?
How do I write Testable Javascript?How do I write Testable Javascript?
How do I write Testable Javascript?
Gavin Pickin
 
Getting your Hooks into Cordova
Getting your Hooks into CordovaGetting your Hooks into Cordova
Getting your Hooks into Cordova
Gavin Pickin
 
Setting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusionSetting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusion
Gavin Pickin
 

More from Gavin Pickin (9)

Itb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin PickinItb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin Pickin
 
Containerizing ContentBox CMS
Containerizing ContentBox CMSContainerizing ContentBox CMS
Containerizing ContentBox CMS
 
ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...
ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...
ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 VueJS cod...
 
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEAN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
 
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
 
Just Mock It - Mocks and Stubs
Just Mock It - Mocks and StubsJust Mock It - Mocks and Stubs
Just Mock It - Mocks and Stubs
 
How do I write Testable Javascript?
How do I write Testable Javascript?How do I write Testable Javascript?
How do I write Testable Javascript?
 
Getting your Hooks into Cordova
Getting your Hooks into CordovaGetting your Hooks into Cordova
Getting your Hooks into Cordova
 
Setting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusionSetting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusion
 

Recently uploaded

GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
Zilliz
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 

Recently uploaded (20)

GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 

3 WAYS TO TEST YOUR COLDFUSION API

  • 1. 3 WAYS TO TEST YOUR COLDFUSION API Gavin Pickin cf.Objective() 2017
  • 2. Agenda ● Who Am I? ● State of the Room? ● CF API ● Ways to test your API? ● Overview of Testing Tools ● Using Testing in your Workflow ● Installing Jasmine ● Installing Testbox ● Live Demo
  • 3. Who am I? Gavin Pickin – developing Web Apps since late 90s ● Software Consultant for Ortus Solutions ● ContentBox Evangelist What else do you need to know? ● Blog - http://www.gpickin.com ● Twitter – http://twitter.com/gpickin ● Github - https://github.com/gpickin Let’s get on with the show.
  • 4. State of the Room ● A few questions for you guys ● If you have arms, use them.
  • 5. APIs in CFML Most CF Apps are moving towards providing an API for multiple consumers CF has many REST API Solutions and even more with CF 2016 ● Built in CF ● Built in Railo/Lucee ● Coldbox API ● Taffy
  • 6. Ways to Test your Code ● Click around in the browser yourself ● Setup Selenium / Web Driver to click around for you ● Structured Programmatic Tests
  • 7. Types of Testing ● Black/White Box ● Unit Testing ● Integration Testing ● Functional Tests ● System Tests ● End to End Tests ● Sanity Testing ● Regression Test ● Acceptance Tests ● Load Testing ● Stress Test ● Performance Tests ● Usability Tests ● + More
  • 8.
  • 9. Integration Testing ● Integration Tests several of the pieces together ● Most of the types of tests are variations of an Integration Test ● Can include mocks but can full end to end tests including DB / APIs
  • 10. Unit Testing “unit testing is a software verification and validation method in which a programmer tests if individual units of source code are fit for use. A unit is the smallest testable part of an application” - wikipedia
  • 11. Unit Testing can... ● Can improve code quality -> quick error discovery ● Code confidence via immediate verification ● Can expose high coupling ● Will encourage refactoring to produce > testable code ● Remember: Testing is all about behavior and expectations
  • 12. Styles – TDD vs BDD ● TDD = Test Driven Development ○ Write Tests ○ Run them and they Fail ○ Write Functions to Fulfill the Tests ○ Tests should pass ○ Refactor in confidence Test focus on Functionality
  • 13. Styles - TDD vs BDD ● BDD = Behavior Driven Development Actually similar to TDD except: ● Focuses on Behavior and Specifications ● Specs (tests) are fluent and readable ● Readability makes them great for all levels of testing in the organization Hard to find TDD examples in JS that are not using BDD describe and it blocks
  • 14. TDD Example Test( ‘Email address must not be blank’, function(){ notEqual(email, “”, "failed"); });
  • 15. BDD Example Describe( ‘Email Address’, function(){ It(‘should not be blank’, function(){ expect(email).not.toBe(“”); }); });
  • 20. CF Testing Tools * MxUnit was the standard * TestBox is the new standard Other options
  • 21. TestBox TestBox is a next generation testing framework for ColdFusion (CFML) that is based on BDD (Behavior Driven Development) for providing a clean obvious syntax for writing tests. It contains not only a testing framework, runner, assertions and expectations library but also ships with MockBox, A Mocking & Stubbing Framework,. It also supports xUnit style of testing and MXUnit compatibilities.
  • 22. TestBox TDD Example function testHelloWorld(){           $assert.includes( helloWorld(), ”world" );      }
  • 23. TestBox BDD Example describe("Hello world function", function() { it(”contains the word world", function() { expect(helloWorld()).toContain("world"); }); });
  • 24. TestBox New BDD Example feature( "Box Size", function(){     describe( "In order to know what size box I need               As a distribution manager               I want to know the volume of the box", function(){         scenario( "Get box volume", function(){             given( "I have entered a width of 20                 And a height of 30                 And a depth of 40", function(){                 when( "I run the calculation", function(){                       then( "the result should be 24000", function(){
  • 25. JS Testing Tools *There are a few choices
  • 26. Main JS Testing Players Jasmine, Mocha and QUnit
  • 27. Jasmine *Jasmine comes ready to go out of the box *Fluent Syntax – BDD Style *Includes lots of matchers *Has spies included *Very popular, lots of support *Angular uses Jasmine with Karma (CLI) *Headless running and plays well with CI servers
  • 28. Jasmine - Cons Async testing in 1.3 can be a headache *Async testing in 2.0 is hard to find blog posts on (I need to write one) *Expects *spec.js suffix for test files *This can be modified depending on how you are running the tests
  • 29. Jasmine – Sample Test describe("Hello world function", function() { it(”contains the word world", function() { expect(helloWorld()).toContain("world"); }); });
  • 30. Mocha *Simple Setup *Simple Async testing *Works great with other Assertion libraries like Chai ( not included ) *Solid Support with CI Servers, with Plugins for others *Opinion says Mocha blazing the trail for new features
  • 31. Mocha - Cons *Requires other Libraries for key features *No Assertion Library included *No Mocking / Spied included *Need to create the runner manually *Newer to the game so not as popular or supported as others but gaining traction.
  • 32. Mocha – BDD Sample Test var expect = require('chai').expect; describe(’Hello World Function', function(){ it('should contain the word world', function(){ expect(helloWorld()).to.contain(’world'); }) })
  • 33. QUnit *The oldest of the main testing frameworks *Is popular due to use in jQuery and age *Ember’s default Unit testing Framework
  • 34. QUnit - Cons *Development slowed down since 2013 (but still under development) *Syntax – No BDD style *Assertion libraries – limited matchers
  • 35. QUnit – Sample Test QUnit.test( "ok test", function( assert ) { assert.ok( true, "true succeeds" ); assert.ok( "non-empty", "non-empty string succeeds" ); assert.ok( false, "false fails" ); assert.ok( 0, "0 fails" ); assert.ok( NaN, "NaN fails" ); assert.ok( "", "empty string fails" ); assert.ok( null, "null fails" ); assert.ok( undefined, "undefined fails" );
  • 36. Spaghetti Javascript Photo Credit – Kombination http://www.kombination.co.za/wp-content/uploads/2012/10/baby_w_spaghetti_mess_4987941.jpg
  • 39. Refactoring Spaghetti *Things to refactor to make your code testable *Code should not be one big chunk of Javascript in onReady() *Deep nested callbacks & Anon functions cannot easily be singled out and tested *Remove Tight Coupling – DOM access for example
  • 40. Refactoring Spaghetti *Lets look at some code *This isn’t BEST PRACTICE, its BETTER PRACTICE than you were doing *Its not really refactoring if you don’t have tests, its “moving code and asking for trouble” Kev McCabe
  • 41. Object Literals var personObjLit = { ssn: ’xxxxxxxx', age: '35', name: 'Gavin Pickin', getAge: function(){ return this.age; }, getName: function() { return this.name; } };
  • 42. Module Pattern var personObjLit2 = function() { ssn = ’xxxxxxx'; age = '35'; name = 'Gavin Pickin’; return { getAge: function(){ return age; }, getName: function() { return name; } }; };
  • 43. Using Testing in your Workflow *Using HTML Test Runners *Keep a Browser open *F5 refresh tests
  • 44. Command Line Tests *Run Jasmine – manual *Run tests at the end of each section of work *Run Grunt-Watch – automatic *Runs Jasmine on every file change *Grunt can run other tasks as well, minification etc
  • 45. Testing in your IDE *Browser Views *Eclipse allows you to open files in web view – uses HTML Runner *Run Jasmine / Grunt / Karma in IDE Console *Fairly Easy to setup *See Demo– Sublime Text 2 (if we have time)
  • 46. Live Demo and Examples *Install / Run Jasmine Standalone for Browser *Install / Run Jasmine with NodeJs *Install / Run Jasmine with Grunt Watch *Install / Run Testbox in Browser
  • 47. Install / Run Jasmine for In-Browser Testing Download standalone package from Github (I have 2.1.3) https://github.com/jasmine/jasmine/tree/master/dist Unzip into your /tests folder Run /tests/SpecRunner.html to see example tests
  • 49. Installing Jasmine for in Browser Testing http://www.testableapi.local.com:8504/tests/SpecRunner.html
  • 50. SpecRunner Setup Jasmine Browser Test <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Jasmine Spec Runner v2.1.3</title> <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.1.3/jasmine_favicon.png"> <link rel="stylesheet" href="lib/jasmine-2.1.3/jasmine.css”> <script src="lib/jasmine-2.1.3/jasmine.js"></script> <script src="lib/jasmine-2.1.3/jasmine-html.js"></script> <script src="lib/jasmine-2.1.3/boot.js"></script> <!-- include source files here... --> <script src="../js/services/loginService.js"></script> <!-- include spec files here... --> <script src="spec/loginServiceSpec.js"></script> </head> <body> </body>
  • 51. Installing Jasmine with NodeJS Assuming you have NodeJs Installed… install Jasmine $ npm install jasmine jasmine@2.2.1 node_modules/jasmine ├── exit@0.1.2 ├── jasmine-core@2.2.0 └── glob@3.2.11 (inherits@2.0.1, minimatch@0.3.0)
  • 52. Installing Jasmine with NodeJS Once Jasmine is installed in your project $ Jasmine init
  • 53. Installing Jasmine with NodeJS Edit Jasmine.json to update Locations for Spec Files and Helper Files { "spec_dir": "spec", "spec_files": [ "**/*[sS]pec.js" ], "helpers": [ "helpers/**/*.js" ] }
  • 54. Running Jasmine Tests with NodeJS $ Jasmine Started F Failures: 1) A suite contains spec with an expectation Message: Expected true to be false. Stack: Error: Expected true to be false. at Object.<anonymous> (/Users/gavinpickin/Dropbox/Apps/testApp/www/spec/test_spec.js:3:1 8) 1 spec, 1 failure
  • 55. Running Jasmine Tests with NodeJS *Jasmine-Node is great for Node *Jasmine Node doesn’t have a headless browser *Hard to test Browser code *So what should I use?
  • 56. Installing Jasmine with Grunt Watcher *Install Grunt npm install grunt *Install Grunt – Jasmine npm install grunt-contrib-jasmine *Install Grunt – Watch npm install grunt-contrib-watch
  • 57. Configuring Jasmine with Grunt Watcher // gruntfile.js - https://gist.github.com/gpickin/1e1e7902d1d3676d23c5 module.exports = function (grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('node_modules/grunt/package.json'), jasmine: { all: { src: ['js/*.js' ], options: { //'vendor': ['path/to/vendor/libs/*.js'], 'specs': ['specs/*.js' ], '--web-security': false }
  • 58. Configuring Jasmine with Grunt Watcher // gruntfile.js part 2 watch: { js: { files: [ 'js/*.js', 'specs/*.js', ], tasks: ['jasmine:all'] } }
  • 59. Configuring Jasmine with Grunt Watcher // gruntfile.js part 3 grunt.loadNpmTasks('grunt-contrib-jasmine'); grunt.loadNpmTasks('grunt-contrib-watch'); };
  • 60. Example Jasmine Spec with Grunt Watcher describe("Forgotten Password Form", function() { it("should warn you if the email is invalid before making Ajax Call", function() { expect( isEmailInputInvalid('') ).toBe(true); expect( isEmailInputInvalid('dddddddddd') ).toBe(true); expect( isEmailInputInvalid('dddddd@') ).toBe(true); expect( isEmailInputInvalid('dddddd@ddddd') ).toBe(true); expect( isEmailInputInvalid('dddddd@ddddddd.') ).toBe(true); expect( isEmailInputInvalid('dddddd@ddddddd.com') ).toBe(false);
  • 61. Example Jasmine Spec with Grunt Watcher describe("Login Form", function() { it("should set status correct status message with successful Ajax Response", function() { spyOn( window, "setStatusMessage"); processLoginAjaxDone('{"RESULT":"200"}'); expect(setStatusMessage).toHaveBeenCalled(); expect(setStatusMessage).toHaveBeenCalledWith( ‘TARDIS Access Granted - Please wait for the Doctor to take you for a spin'); });
  • 62. Example Jasmine Spec with Grunt Watcher describe("Login API", function() { it("should return a failing Ajax Response", function() { spyOn( window, "processLoginAjaxDone"); loginButtonEventHandlerProcess( 'gavin@gavin.co.nz', 'password'); expect(processLoginAjaxDone).toHaveBeenCalled(); expect(processLoginAjaxDone).toHaveBeenCalledWith( ‘{"RESULT":400}'); expect(processLoginAjaxFail).not.toHaveBeenCalled();
  • 63. Whats wrong with that? describe("Login API", function() { it("should return a failing Ajax Response", function() { spyOn( window, "processLoginAjaxDone"); loginButtonEventHandlerProcess( 'gavin@gavin.co.nz', 'password'); expect(processLoginAjaxDone).toHaveBeenCalled(); expect(processLoginAjaxDone).toHaveBeenCalledWith( ‘{"RESULT":400}'); expect(processLoginAjaxFail).not.toHaveBeenCalled(); });
  • 64. Unit Tests and Async Calls *You want Unit Tests to test the unit and not it’s dependencies *You want Unit Tests to run quick *You should mock the API in the Ajax call *But we want to test the API *So essentially, we’re writing an integration test.
  • 65. How to wait for Async describe("Login API", function() { beforeEach(function( done ) { spyOn( window, "processLoginAjaxDone").and.callFake( function(){ done(); }); spyOn( window, "processLoginAjaxFail").and.callFake( function(){ done(); }); loginButtonEventHandlerProcess('gavin@gavin.co.nz', 'password'); }); it("should return a failing Ajax Response", function() { }); });
  • 66. How to wait for Async describe("Login API", function() { beforeEach(function( done ) { … }); it("should return a failing Ajax Response", function() { expect(processLoginAjaxDone).toHaveBeenCalled(); expect(processLoginAjaxDone).toHaveBeenCalledWith( '{"RESULT":400}'); expect(processLoginAjaxFail).not.toHaveBeenCalled(); });
  • 67. Running Jasmine with Grunt Watcher
  • 68. Running Jasmine with Grunt Watcher
  • 69. Installing Testbox *Install Testbox – Easy Thanks to Commandbox *box install testbox *Next, decide how you want to run Testbox
  • 70. Create a runner.cfm *<cfsetting showDebugOutput="false"> *<!--- Executes all tests in the 'specs' folder with simple reporter by default ---> *<cfparam name="url.reporter" default="simple"> *<cfparam name="url.directory" default="tests.specs"> *<cfparam name="url.recurse" default="true" type="boolean"> *<cfparam name="url.bundles" default=""> *<cfparam name="url.labels" default="">
  • 71. Create a Test Suite // tests/specs/CFCTest.cfc component extends="testbox.system.BaseSpec" { function run() { it( "will error with incorrect login", function(){ var oTest = new cfcs.userServiceRemote(); expect( oTest.login( 'gavin@gavin.com', 'topsecret').result ).toBe('400'); }); }
  • 72. Create a 2nd Test Suite // tests/specs/APITest.cfc component extends="testbox.system.BaseSpec" { function run() { describe("userService API Login", function(){ it( "will error with incorrect login", function(){ var email = "gavin@gavin.com"; var password = "topsecret”; var result = ""; http url="http://www.testableapi.local.com:8504/cfcs/userServiceRemote.cfc?method=log in&email=#email#&password=#password#" result="result”; expect( DeserializeJSON(result.filecontent).result ).toBe('400'); }); });
  • 73. Running Testbox with runner.cfm
  • 74. Running Testbox with Grunt Watch *Install Testbox Runner – Thanks Sean Coyne *npm install testbox-runner *Install Grunt Shell *npm install grunt-shell *Add Grunt Configuration
  • 75. Adding TextBox Config 1 module.exports = function (grunt) { grunt.loadNpmTasks('grunt-shell'); grunt.initConfig({ … }) }
  • 76. Adding TextBox Config 2 Watch: { … cfml: { files: [ "cfcs/*.cfc"], tasks: [ "testbox" ] } }
  • 77. Adding TextBox Config 3 shell: { testbox: { command: "./node_modules/testbox-runner/index.js --colors --runner http://www.testableapi.local.com:8504/tests/r unner.cfm --directory /tests/specs --recurse true”
  • 78. Adding TextBox Config 4 grunt.registerTask("testbox", [ "shell:testbox" ]); grunt.loadNpmTasks('grunt-contrib-jasmine'); grunt.loadNpmTasks('grunt-contrib-watch');
  • 79. Adding TextBox Config 5 js: { files: [ 'js/*.js', 'specs/*.js', "cfcs/*.cfc” ], tasks: ['jasmine:all'] },
  • 80. GruntFile.js Gists Jasmine https://gist.github.com/gpickin/1e1e7902d1d36 76d23c5 Jasmine + Testbox https://gist.github.com/gpickin/9fc82df3667ee b63c7e7
  • 82. Testbox Runner JSON *Testbox has several runners, you have seen the HTML one, this Runner uses the JSON runner and then formats it. *http://www.testableapi.local.com:8504/tests/runner.cfm?rep orter=JSON&directory=%2Ftests%2Fspecs&recurse=true
  • 83. Running in Sublime Text 2 *Install PackageControl into Sublime Text *Install Grunt from PackageControl *https://packagecontrol.io/packages/Grunt *Update Grunt Sublime Settings for paths { "exec_args": { "path": "/bin:/usr/bin:/usr/local/bin” } } *Then Command Shift P – grunt