3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
ortussolutions
760 views
87 slides
Nov 22, 2017
Slide 1 of 87
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
About This Presentation
Most projects in CF now involve creating some type of consumable CFC Endpoint or API Service... do you Unit test your API, do you use Integration Tests on your API? How many ways do you test your API? Not all tests are created equal.
Description
Most projects in CF now involve creating some type of...
Most projects in CF now involve creating some type of consumable CFC Endpoint or API Service... do you Unit test your API, do you use Integration Tests on your API? How many ways do you test your API? Not all tests are created equal.
Description
Most projects in CF now involve creating some type of consumable CFC Endpoint or API Service... do you Unit test your API, do you use Integration Tests on your API? How many ways do you test your API? Not all tests are created equal.
We build our CFCs and CF API to be consumed with CF Apps, Mobile Apps, Javascript apps and devices we haven’t even thought about yet. To be smart developers we need to be able to test our CFC endpoints, and the code that uses those endpoints.
We’ll learn how to test your API serverside with Testbox and Clientside with Jasmine.
With Testbox and Jasmine both using BDD, your test code can almost be isomorphic.
Attendees should have some exposure to CFCs as endpoints, or CF API creations, and consuming with other languages/devices, in this case, JavaScript.
## Attendees will learn
How to use Testbox to test your CFCs 2 different ways
Different types and ways to test JavaScript
Overview of client/server side testing tools
Building testing into your workflow
You are one of many that are not testing your APIs thoroughly
Size: 2.31 MB
Language: en
Added: Nov 22, 2017
Slides: 87 pages
Slide Content
3 WAYS TO TEST YOUR COLDFUSION API Gavin Pickin CFSummit() 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.
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(“”); }); });
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(){ // call the method with the arguments and test the outcome expect ( myObject.myFunction(20,30,40) ).toBe( 24000 ); }); }); }); }); }); });
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
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 Testbox with Grunt Watch Install / Run Grunt Watch inside Sublime Text 2
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
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:18) 1 spec, 1 failure Finished in 0.009 seconds
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 Note: On Mac, I also needed to install Grunt CLI npm install –g grunt-cli
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('[email protected]') ).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'); }); });
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('[email protected]', '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, write some tests in the tests/specs folder
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( '[email protected]', 'topsecret').result ).toBe('400'); }); } }
Create a 2 nd 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 = "[email protected]"; var password = "topsecret”; var result = ""; http url="http://www.testableapi.local.com:8504/cfcs/userServiceRemote.cfc?method=login&email=#email#&password=#password#" result="result”; expect( DeserializeJSON(result.filecontent).result ).toBe('400'); }); }); } }
Running Testbox Now, decide how you want to run Testbox CommandBox CLI Browser CLI with Grunt IDE
Running Testbox via Comman dBox CommandBox has some handy features to make TestBox tests easier. Just add to box.json "testbox":{ "runner" :"http://www.testableapi.local.com:8504/tests/runner.cfm" } $ testbox run
Running Testbox via Comman dBox Now, what if you don’t want to run the tests again everytime you save a file? $ testbox watch
Browser - 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=""> <!--- Include the TestBox HTML Runner ---> <cfinclude template="/testbox/system/runners/HTMLRunner.cfm" >
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?reporter=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 ERRORS ON MY MACHINE TODAY
Running in Sublime Text 2
ColdBox REST API It’s easy to get started with ColdBox Rest with CommandBox’s scaffolding. ## create app coldbox create app name=MyRestAPP skeleton=rest ## Start up a server with rewrites on port 8505 server start port=8505
ColdBox REST API Let’s have a look
My Testing Videos NVCFUG Meetup 2017 - Testing is natural, testing is fun, not everybody does it but everybody should! http://experts.adobeconnect.com/testboxortusinh/ ODW 2015 - Testing my API with TestBox on Server and Jasmine on Client http://experts.adobeconnect.com/p6akdiyds21/ CBW 2014 - Mockbox, get ready to mock your socks off Video: https://vimeo.com/112238773 Slides: https://docs.google.com/file/d/0B_65i6I500NiN1BoVmVmaFh5dlBXd2ljV1NuY1d3WEtxdUt3/edit
Other Testing Videos ODW2017 - Testing my Non-ColdBox site with TestBox - Nolan Erck https://vimeo.com/241813746 ODW 2016 - Testing Automation - Luis Majano https://vimeo.com/194169908 ODW 2016 - Integrated - A TestBox packe for even better Integration Tests - Eric Peterson https://vimeo.com/194168660 ODW 2016 - Code Coverage for CFML - Brad Wood https://vimeo.com/194134971 ODW 2015 - TestBox BDD - Luis Majano https://vimeo.com/148262563 CBDW 2013 - Mocking and Stubbing - Luis Majano https://vimeo.com/groups/coldbox/videos/68861083
My Other Videos ODW 2017 - Real World ContentBox Microservices https://vimeo.com/241813747 Containers Roadshow 2017 - Playing with Docker with Gavin Pickin https://vimeo.com/groups/coldbox/videos/236135671 ContentBox Roadshow 2016 - What's new with ContentBox 3 https://t.co/CdPTM4FFAh ContentBox Roadshow 2016 - ContentBox Administration 101 http://experts.adobeconnect.com/p2vx8nqb3wd/ ContentBox Roadshow 2016 - ContentBoxContentBox Modules Deep Dive http://experts.adobeconnect.com/p7d7h77mivb/ ODW 2016 - ContentBox CMS Deep Dive http://experts.adobeconnect.com/p4yd4a6n5bj/
My Other Videos - cont ODW 2015 - Relax with ColdBox RESTFul Services http://experts.adobeconnect.com/p67qaf48xum/ ODW 2015 - Getting Started With ContentBox http://experts.adobeconnect.com/p249qn543je/ CBDW 2013 - Learning ColdBox through Testing https://vimeo.com/groups/coldbox/videos/69995315