Integration testing
Allows you to setup your game room for testing specific cases.
Starting from client-side:
- Create new room passing test name in options:
game.joinOrCreate("MyGame", { test: "testName" })
- New "MyGame" room is created
- Server-side calls integration hooks named "testName"
- Your game room is now ready for testing
- Start the game, interact with it like usual and inspect the results
Setup integration hooks
First you need to define integration hooks and what they'll do.
- Create new directory in your server game package:
game-mygame-server/src/integration
- Create new file for your setup:
/src/integration/attack3.ts
export const attack3: IntegrationHooks<MyGameState> = {
data: {
shuffleDeck: false,
},
init: function (state, context) {
state.attackPoints = 3
const clients = ["test1", "test2"]
clients.forEach((i) => context.addClient(i))
},
}
IntegrationHooks object defines hooks callbacks and persistent data:
Hooks callbacks
init
- will be called during room creation, but after onInitGame, so your game state object is already preparedstartPre
- called right before the game starts.state.isGameStarted
is alreadytrue
and room's onStartGame has not yet been called.startPost
- called last during game start sequence, after onStartGame.
Integration data
data
- an object for you to define additional flags available in the game's room. It'll be available in room's class underthis.currentIntegration.data
(readonly).
Example
/src/integration/attack3.ts
export const attack3: IntegrationHooks<MyGameState> = {
data: {
shuffleDeck: false,
},
// ...
}
/src/index.ts - Room class
onStartGame() {
const { state } = this
const { shuffleDeck } = this.currentIntegration.data
return [
shuffleDeck && new commands.ShuffleChildren(state.deck)
].filter(cmd => cmd)
}
Add hooks to the Room
Hooks are defined so now we can pass them to the Room class. In example below we might keep many integration objects in one /integration/attack.ts
file.
/src/index.ts - Room class
import * as integrationAttack from "./integration/attack"
import * as integrationUi from "./integration/ui"
export default class MyGame extends Room<MyGameState> {
possibleActions = new Set<ActionTemplate<MyGameState>>(actions)
integrationHooks = {
...integrationAttack,
...integrationUi,
}
// ...
}
Run
With the server-side setup we can finally enter the game from client-side and see the game being prepared differently than usual:
game.joinOrCreate("MyGame", { test: "attack3" })
Tips
What's left for you is to setup your own e2e testing environment.
Setup a test route in your webapp to quickly join the room with an integration test like:
locahost:8000/game/MyGame/autoplay?test=attack3
.Make quick function to open up these URLs.
// In my Cypress setup I've created a support function
Cypress.Commands.add("testRoom", (roomName, testName) => {
cy.visit(`/game/${roomName}/autoplay?test=${testName}`)
})
// And call it like so
cy.testRoom("MyGame", "attack3")