Requires ColdBox 4.2+ and TestBox 2.3+
Install the package from ForgeBox:
box install integrated
Important:
Add the Integrated lib directory to this.javaSettings
in your *tests*
directory's Application.cfc
.
this.javaSettings = { loadPaths = [ "Integrated/lib" ], reloadOnChange = false };
You might also be interested in integrated-commands
, a CommandBox module for scaffolding Integrated tests quickly.
Change your Integration tests to extend from Integration.BaseSpecs.ColdBoxBaseSpec
. (Make sure to call the parent class's beforeAll
method.)
component extends="Integrated.BaseSpecs.ColdBoxBaseSpec" {
function beforeAll() {
// Make sure to call the parent class's beforeAll() and afterAll() methods.
super.beforeAll();
}
function afterAll() {
super.afterAll();
}
}
Start using an easy, fluent API for your integration tests!
function run() {
describe( "Registering", function() {
it( "allows a new user to register for the site", function() {
this.visitEvent('register.new')
.type('Eric', 'name')
.type('mYAw$someP2ssw0rd!', 'password')
.press('Register')
.seeTitleIs('Home')
.see('Welcome, Eric!');
});
});
}
You can see all the different methods you can call in the API docs.
You can add automatic database transactions by adding one line to the top of your spec:
component extends="Integrated.BaseSpecs.ColdBoxBaseSpec" {
this.useDatabaseTransactions = true;
function run() {
describe( "Registering", function() {
it( "allows a new user to register for the site", function() {
this.visitEvent('register.new')
.type('Eric', 'name')
.type('mYAw$someP2ssw0rd!', 'password')
.press('Register')
.seeTitleIs('Home')
.see('Welcome, Eric!');
});
});
}
}
Easily add database transactions around your tests by adding this one property to your test:
this.useDatabaseTransactions = true;
By default, we clear out the session scope on each request. If you want to persist the session scope across requests, simply add this.persistSessionScope = true;
to the top of your spec. Note: this will happen for all tests in the file.
To create your own framework specific BaseSpec, first extend the Integrated.BaseSpecs.AbstractBaseSpec
component.
component extends="Integrated.BaseSpecs.AbstractBaseSpec" {
function beforeAll() {
// IMPORTANT! Don't forget to call `beforeAll()` and `afterAll()`!
super.beforeAll(
// your setup here
);
}
function afterAll() {
super.afterAll();
}
}
The beforeAll
method takes four separate engines that drive Integrated:
/**
* Sets up the needed dependancies for Integrated.
*
* @requestEngine Integrated.Engines.Request.Contracts.RequestEngine
* @frameworkEngine Integrated.Engines.Assertion.Contracts.FrameworkAssertionEngine
* @domEngine Integrated.Engines.Assertion.Contracts.DOMAssertionEngine
* @interactionEngine Integrated.Engines.Interaction.Contracts.InteractionEngine
*
* @return Integrated.BaseSpecs.AbstractBaseSpec
*/
public AbstractBaseSpec function beforeAll(
required RequestEngine requestEngine,
required FrameworkAssertionEngine frameworkEngine,
required DOMAssertionEngine domEngine,
required InteractionEngine interactionEngine
);
In your base spec, you can return any combination of these four engines to power Integrated. For instance, you may wish to specify a different RequestEngine
and FrameworkAssertionEngine
for your new base spec but use JSoup for the DOMAssertionEngine
and the InteractionEngine
. Or, you could use Selenium based engines for every one of the required engines. It's up to you.
You can look at Integrated.BaseSpecs.ColdBoxBaseSpec
for how this is done for ColdBox.
Each engine has an Interface that new engines must conform to as well as an abstract spec they should pass.
// Integrated.Engines.Request.MyAwesomeRequestEngine
component implements="Integrated.Engines.Request.Contracts.RequestEngine" {
// your implementation here
}
component extends="tests.specs.unit.Engines.Request.Contracts.RequestEngineTest" {
function getCUT() {
return new Integrated.Engines.Request.MyAwesomeRequestEngine();
}
}
Note: each engine's abstract spec may be slightly different in how they are set up. Take a look at the specs to see the details.
This package is heavily inspired by Jeffrey Way's Integrated package for Laravel. I learned about it at Laracasts, which I consider my best programming resource regardless of the fact that I have never deployed a line of PHP code.