TestBox : Behavior Driven Development (BDD)
API DocsSourceSupportBoxLang
v6.x
v6.x
  • Introduction
    • Release History
      • What's New With 6.3.0
      • What's New With 6.2.1
      • What's New With 6.2.0
      • What's New With 6.1.0
      • What's New With 6.0.1
      • What's New With 6.0.0
    • About This Book
      • Author
  • Getting Started
    • Overview
    • Installation
      • IDE Tools
      • MXUnit Compatibility
    • Writing Tests
    • Running Tests
      • BoxLang CLI Runner
      • CommandBox Runner
      • Web Runner
      • Bundle(s) Runner
      • Directory Runner
      • ANT Runner
      • NodeJS Runner
      • Global Runner
      • Test Browser
    • BDD Tests
      • Bundles: Group Your Tests
      • Suites: Describe Your Tests
        • Dynamic Suites
      • Specs
      • Expectations
      • Suite Groups
        • Given-When-Then Blocks
      • Life-Cycle Methods
      • Life-Cycle Data Binding
      • Specs and Suite Labels
      • Skipping Specs and Suites
      • Focused Specs and Suites
      • Spies & Mocking
      • Asynchronous Testing
      • Running Tests
      • Reporters
    • xUnit Tests
      • Test Bundles
      • Life-Cycle Methods
      • Test Methods
      • Assertions
      • Test and Suite Labels
      • Skipping Tests and Suites
      • Spies and Mocking
      • Asynchronous-Testing
      • Running Tests
      • Reporters
  • Digging Deeper
    • Life-Cycle Annotations
    • Assertions
      • Custom Assertions
    • Expectations
      • Matchers
      • Not Operator
      • Expecting Exceptions
      • Custom Matchers
    • Output Utilities
    • Runner Listeners
    • Reporters
      • Custom Reporters
    • Modules
    • Code Coverage
      • Running Code Coverage
      • Configuring Code Coverage
      • Known Behaviors
    • Continous Integration
      • Github Actions
      • Gitlab
      • Travis
  • Mocking
    • MockBox
      • What is Mocking?
      • Our Approach and Benefits
      • Creating MockBox
      • Creating a Mock Object
      • Creating a Stub Object
      • Mocking Methods
        • $() Method
        • $args() Method
        • $getProperty() Method
        • $property() Method
        • $querySim() Method
        • $results() Method
        • $spy()
        • $throws() Method
      • Verification Methods
        • $count()
        • $times() or $verifyCallCount()
        • $never()
        • $atLeast()
        • $once()
        • $atMost()
        • $callLog()
        • $reset()
        • $debug()
      • Some Examples
      • Conclusion
    • Mocking Data
Powered by GitBook

Social Media

  • YouTube
  • x
  • FaceBook
  • LinkedIn

Downloads

  • CommandBox
  • BoxLang
  • Try BoxLang

Support

  • Professional
  • Community
  • Slack
  • CFCasts

Copyright & Register Trademark by Ortus Solutions, Corp & Ortus Software, LLC

On this page
  • Styles
  • Assertions & Expectations
  • Life-Cycles
  • Utilities
  • Runners
  • Reports
  • Useful Resources

Was this helpful?

Edit on GitHub
Export as PDF
  1. Getting Started

Overview

A quick overview of TestBox

PreviousAuthorNextInstallation

Was this helpful?

TestBox is a next-generation testing framework for the JVM language and ColdFusion (CFML) language based on (Behavior Driven Development) for providing a clean, obvious syntax for writing tests. It contains not only a testing framework, console/web runner, assertions, and expectations library but also ships with several mocking utilities.

Styles

In TestBox you can write your tests in two different styles or approaches.

BDD (Behavior Driven Development)

BDD stands for behavior-driven development and is highly based on creating specifications and expectations of results in a readable DSL (Domain Specific Language). You are not focusing on a specific unit and method to test, but on functionality, features and more. This can encompass not only unit but also integration testing. You have several methods that you can use in order to denote functionality and specifications:

  • describe()

  • feature()

  • story()

  • given(), when(), then()

  • it() or test()

describe( "My calculator features", () => {
	
	beforeEach( () => {
		variables.calc = new Calculator()
	} )
		
	// Using expectations library
	it( "can add", () => {
		expect( calc.add(1,1) ).toBe( 2 )
	} )
	
	// Using assert library
	test( "it can multiply", () => {
		$assert.isEqual( calc.multiply(2,2), 4 )
	} )
} )

xUnit (Test Driven Development)

xUnit style of testing is the more traditional TDD or test-driven development approach where you create a test case bundle class that matches the software under test, and for each method in the SUT, you create a test method in the test bundle class.

@DisplayName "My calculator features"
class{

	property calc;
	
	function setup(){
		calc = new Calculator()
	}
	
	// Function name includes the word 'test'
	// Using expectations library
	function testAdd(){
		expect( calc.add(1,1) ).toBe( 2 )
	}
		
	// Any name, but with a test annotation
	// Using assertions library
	@DisplayName "It can multiply two operands"
	@test
	function itCanMultiply(){
		$assert.isEqual( calc.multiply(2,2), 4 )
	}
}

Assertions & Expectations

We also give you two ways to do assertions:

// Assertions
assert( expression, "custom message" )

// Expectations
expect( structKeyExists( handler, "mixinTest" ) ).toBeTrue();
expect( structKeyExists( handler, "repeatThis" ) ).toBeTrue();
expect( structKeyExists( handler, "add" ) ).toBeTrue();
expect( target.$callLog().relocate[ 1 ].url ).toInclude( "dashboard" );

Life-Cycles

beforeEach( function( currentSpec ){
    setup();
    target = prepareMock( getInstance( "coldbox.system.FrameworkSupertype" ) );
} );

afterEach( function( currentSpec ){
    getCache( "template" ).clearAll();
    variables.scheduler.shutdown();
} );


function beforeAll() {
	super.beforeAll();
	
	// Login User
	variables.loggedInData = loginUser();
	
	variables.loggedInUserId = variables.loggedInData.user.getUserId();
	
	variables.testTimeOffEmployeeId = qb
		.select( "FK_userId" )
		.from( "timeOff" )
		.where( "requestType", "vacation" )
		.first()
		.FK_userId;
}

function afterAll() {
	variables.userService.clearCaches()
}
function setup() {
	super.setup();

	if ( !isNull( request.testUserData ) ) {
		getRequestContext().setValue( "x-auth-token", request.testUserData.token.access_token );
	}

	return;
}

function tearDown(){
	request.clear()
}

function beforeTests() {
	
	// Login User
	variables.loggedInData = loginUser();
	
	variables.loggedInUserId = variables.loggedInData.user.getUserId();
	
	variables.testTimeOffEmployeeId = qb
		.select( "FK_userId" )
		.from( "timeOff" )
		.where( "requestType", "vacation" )
		.first()
		.FK_userId;
}

function afterTests() {
	variables.userService.clearCaches()
}

Utilities

TestBox will also offer different utilities:

  • Debug output to a debug buffer

  • Mock classes, methods and properties

  • Extension data mocking and JSON mocking

  • Logging facilities

Runners

You can also execute your tests via the CLI, IDE or the web server.

Reports

TestBox can produce many different types of reports for your test executions:

  • CLI / Console Output

  • VSCode Output

  • JSON

  • XML

  • JUNIT

  • TAP

  • HTML

  • DOC

  • Your own

Here is a few samples:

class{

  function run(){
  	describe( "My calculator features", () => {
	
		beforeEach( () => {
			variables.calc = new Calculator()
		} )
			
		// Using expectations library
		it( "can add", () => {
			expect( calc.add(1,1) ).toBe( 2 )
		} )
		
		// Using assert library
		test( "it can multiply", () => {
			$assert.isEqual( calc.multiply(2,2), 4 )
		} )
	} )
  }

}
/**
 * My calculator features
 */
class{

	property calc;
	
	function setup(){
		calc = new Calculator()
	}
	
	// Function name includes the word 'test'
	// Using expectations library
	function testAdd(){
		expect( calc.add(1,1) ).toBe( 2 )
	}
		
	// Any name, but with a test annotation
	// Using assertions library
	@test
	function itCanMultiply(){
		$assert.isEqual( calc.multiply(2,2), 4 )
	}
}
component{

  function run(){
  	describe( "My calculator features", () => {
	
		beforeEach( () => {
			variables.calc = new Calculator()
		} );
			
		// Using expectations library
		it( "can add", () => {
			expect( calc.add(1,1) ).toBe( 2 )
		} );
		
		// Using assert library
		test( "it can multiply", () => {
			$assert.isEqual( calc.multiply(2,2), 4 )
		} );
	} );
  }

}
/**
 * My calculator features
 */
component{
	
	property calc;
	
	function setup(){
		calc = new Calculator()
	}
	
	// Function name includes the word 'test'
	// Using expectations library
	function testAdd(){
		expect( calc.add(1,1) ).toBe( 2 )
	}
		
	// Any name, but with a test annotation
	// Using assertions library
	function itCanMultiply() test{
		$assert.isEqual( calc.multiply(2,2), 4 )
	}
}

Useful Resources

library, which is a traditional approach to assertions

library, which is a more fluent approach to assertions.

Both approaches also offer different callbacks so you can execute code during different times in the test execution.

BoxLang
BDD
Assertions
Expectations
life-cycle
Approaches to Mocking
Wikipedia Mock Objects
Using mock objects for complex unit tests IBM developerWorks
Unit testing with mock objects IBM developerWorks
Emergent Design by Scott Bain
Mocks Aren't Stubs by Martin Fowler
Runner