Each style has its own life-cycle methods you can discover in their primers. They are callbacks that TestBox calls at specific points in time of testing. They are a great way to setup or tear down things before the entire testing suite or one test case. Here is a short synopsis for each style.
Global callbacks affect the execution of the entire test bundle CFC and all of its suites and specs.
Executes once before all specs for the entire test bundle CFC. A great place to initialize the environment the bundle needs for testing.
Executes once after all specs for the entire test bundle CFC. A great place to teardown the environment the bundle needed for testing.
Executes once so it can capture all your describe
and it
blocks so they can be executed by a TestBox runner.
You can find the API docs for testbox
and the testResults
arguments here: https://s3.amazonaws.com/apidocs.ortussolutions.com/testbox/current/
The following callbacks influence the execution of specification methods: it(), then()
. The great flexibility of the BDD approach is that it allows you to nest describe
, feature
, story
, given
, scenario
, when
suite blocks to create very human readable and organized documentation for your tests. Each suite block can have its own life-cycle methods as well. Not only that, if they are nested, TestBox will walk the tree and call each beforeEach()
and afterEach()
in the order you declare them.
TestBox will walk down the tree (from the outermost suite) for beforeEach()
operations and out of the tree (from the innermost suite) for afterEach()
operations.
Executes before every single spec in a single suite block and receives the currently executing spec and any data you want to bind the specification with. The body
is a closure/lambda that will fire and the data
argument is a way to bind the life-cycle method with a struct of data that can flow down to specs.
The body
closure will receive have the following signature:
Executes after every single spec in a single suite block and receives the currently executing spec and any data you want to bind the specification with. The body
is a closure/lambda that will fire and the data
argument is a way to bind the life-cycle method with a struct of data that can flow down to specs.
The body
closure will receive have the following signature:
Here are some examples:
Executes around the executing spec so you can provide code that will surround the execution of the spec. It's like combining before
and after
in a single operation. The body
is a closure/lambda that will fire and the data
argument is a way to bind the life-cycle method with a struct of data that can flow down to specs. This is the only way you can use CFML constructs that wrap around code like: try/catch, transaction, for, while, etc.
The body
closure will receive have the following signature:
The spec
is the currently executing specification, the suite
is the suite this life-cycle is embedded in and data
is the data binding, if any.
Here is an example:
You can pass in an argument called data
, which is a struct
of dynamic data, to all life-cycle methods. This is useful when creating dynamic suites and specifications. This data
will then be passed into the executing body for each life-cycle method for you.
Here is a typical example:
In addition to the life-cycle methods, you can make any method a life-cycle method by giving it the desired annotation in its function definition. This is especially useful for parent classes that want to hook in to the TestBox life-cycle.
@beforeAll
- Executes once before all specs for the entire test bundle CFC
@afterAll
- Executes once after all specs complete in the test bundle CFC
@beforeEach
- Executes before every single spec in a single describe block and receives the currently executing spec.
@afterEach
- Executes after every single spec in a single describe block and receives the currently executing spec.
@aroundEach
- Executes around the executing spec so you can provide code surrounding the spec.
Below are several examples using script notation.
DBTestCase.cfc (parent class)
PostsTest.cfc
This also helps parent classes enforce their setup methods are called by annotating the methods with @beforeAll
. No more forgetting to call super.beforeAll()
!
You can have as many annotated methods as you would like. TestBox discovers them up the inheritance chain and calls them in reverse order.
beforeTests()
- Executes once before all tests for the entire test bundle CFC
afterTests()
- Executes once after all tests complete in the test bundle CFC
setup( currentMethod )
- Executes before every single test case and receives the name of the actual testing method
teardown( currentMethod )
- Executes after every single test case and receives the name of the actual testing method