BounceUser Guide
Overview
Bounce - use it to test your Bed Apps!
Bounce is a testing framework that makes requests to a Bed App without the overhead of starting a web server, opening ports, and making expensive network connections.
You're still testing your Bed App, you're just cutting out the middle man!
Install
Install Bounce with the Fantom Repository Manager ( fanr ):
C:\> fanr install -r http://repo.status302.com/fanr/ afBounce
To use in a Fantom project, add a dependency to build.fan:
depends = ["sys 1.0", ..., "afBounce 0+"]
Quick Start
1). Create a text file called Example.fan:
using afBounce
using afBedSheet
using afIoc
class Example : Test {
Void testBedApp() {
// given
server := BedServer(AppModule#).startup
client := server.makeClient
// when
client.get(`/index`)
// then
title := Element("#title")
title.verifyTextEq("Bed Bouncing!")
// clean up
server.shutdown
}
}
** A Really Simple Bed App!!!
class AppModule {
@Contribute { serviceType=Routes# }
static Void contributeRoutes(OrderedConfig config) {
config.add(Route(`/index`, Text.fromHtml("""<html><p id="title">Bed Bouncing!</p></html>""")))
}
}
2). Run Example.fan as a Fantom test script ( fant ) from the command line:
C:\> fant Example.fan
-- Run: Example_0::Example.testBedApp...
[info] [afIoc] Adding modules from dependencies of 'afBedSheet'
[info] [afIoc] Adding module definition for afBedSheet::BedSheetModule
[info] [afIoc] Adding module definition for afIocConfig::IocConfigModule
[info] [afIoc] Adding module definition for afIocEnv::IocEnvModule
[info] [afIoc] Adding module definition for Example_0::AppModule
[info] [afIoc]
___ __ _____ _
/ _ | / / _____ _____ / ___/__ ___/ /_________ __ __
/ _ | / /_ / / -_|/ _ / / __// _ \/ _/ __/ _ / __|/ // /
/_/ |_|/___//_/\__|/_//_/ /_/ \_,_/__/\__/____/_/ \_, /
Alien-Factory BedServer v1.0.0, IoC v1.6.0 /___/
BedServer started up in 597ms
Pass: Example_0::Example.testBedApp [1]
Time: 2052ms
***
*** All tests passed! [1 tests, 1 methods, 1 verifies]
***
Usage
Use BedServer to start an instance of your Bed App, and then use BedClient make repeated requests against it. The HTML elements are then used to verify that correct content is rendered.
BedClient is a ButterDish that wraps a Butter instance - all functionality is provided by Butter middleware. BedTerminator is the terminator of the stack, which sends requests to BedServer, which holds the instance of your Bed App.
Verify HTML Content
When queried, the HTML classes (Element, TextBox, etc...) use the last response from the client. The client stores itself in the Actor.locals() map, and the HTML elements implicitly use this value. This means you can define your Elements once (in a mixin if need be) and use them over and over without needing to track response they're querying. Example:
// deinfe your elements
title := Element("h1")
link := Element("#page2")
// use them
client.get(`/index`)
title.verifyTextEq("Home Page")
link.click
title.verifyTextEq("Page2")Inspect the WebSession
It can be useful to inspect, assert against, or even set values in, a client's web session. As the BedClient holds the session, this is easy!
using afBounce
class TestMyBedApp : Test {
Void testBedApp() {
server := BedServer(AppModule#).startup
client := server.makeClient
....
// set values in the user's session
client.webSession["userName"] = "Emma"
// assert against session values
verifyNotNull(client.webSession["shoppingCart"])
}
}
Inject Services Into Tests
BedServer has access to the Ioc registry used by your Bed App, this lets you inject services into your test.
using afBounce
using afIoc
class TestMyBedApp : Test {
@Inject
MyService myService
Void testBedApp() {
server := BedServer(AppModule#).startup
// inject services into test
server.injectIntoFields(this)
...
}
}
Override Services
BedServer lets you specify additional Ioc modules, meaning you can add custom test modules that override or stub out real services with test ones.
using afBounce
class TestMyBedApp : Test {
Void testBedApp() {
server := BedServer(AppModule#)
// override services with test implementations
server.addModule(TestOverrides#)
server.startup
....
}
}
Test Outside The Box!
By creating BedClient with a Butter stack that ends with a real HTTP terminator, Bounce can also be used to test web applications in any environment. Example:
using afBounce
using afButter
class TestFantomFactory : Test {
Void testFantomFactory() {
// add Sizzle to the middleware stack
client := BedClient(Butter.churnOut(
Butter.defaultStack.insert(0, SizzleMiddleware())
))
// make real http requests to your integration environment
client.get(`http://www.fantomfactory.org/pods/afBounce`)
// use sizzle to test
tagLine := Element(".jumbotron h1 + p")
tagLine.verifyTextEq("A library for testing Bed applications!")
}
}
Release Notes
v1.0.0
- Chg: Updated to use Ioc 1.6.0 and BedSheet 1.3.6.
v0.0.6
- New: HTML
Elementclasses with an abundance of helper and verify methods.
v0.0.4
- Chg:
BedTerminatormore closely follows Butter'sHttpTerminator - Chg: Renamed
BedClient.select()toBedClient().selectCss()
v0.0.2
- New: Preview Release