-
Notifications
You must be signed in to change notification settings - Fork 4
3. Setup and Teardown
To help a test suite DRY up any duplicated setup and teardown code, Lilac provides the beforeEach and afterEach functions. As the name implies, the beforeEach function is called once before each spec in the file in which it is defined, and the afterEach function is called once after each spec.
beforeEach and afterEach are not functions you call, they are functions you override. They are "magic" functions that will be called for you automatically if you define them in your test script.
Here is an example test suite that has duplicate set-up and teardown code:
function TestSuites()
describe("Story quest", storyQuestSuite())
endFunction
function storyQuestSuite()
it("should give the player the power sword when the quest starts", powerSwordTest())
it("should make sure that the NPC alias is filled when the quest starts", aliasCheckTest())
it("should make sure the stage gets set to 10 after the quest starts", stageCheckTest())
endFunction
function powerSwordTest()
if MyQuest.IsRunning()
MyQuest.Stop()
endif
MyQuest.Start()
expectInt(Game.GetPlayer().GetItemCount(PowerSword), to, beGreaterThanOrEqualTo, 1)
MyQuest.Stop()
Game.GetPlayer().RemoveItem(PowerSword, 1)
endFunction
function aliasCheckTest()
if MyQuest.IsRunning()
MyQuest.Stop()
endif
QuestAlias.Clear()
MyQuest.Start()
expectRef(QuestAlias.GetActorRef(), notTo, beNone)
MyQuest.Stop()
QuestAlias.Clear()
endFunction
function stageCheckTest()
if MyQuest.IsRunning()
MyQuest.Stop()
endif
MyQuest.SetStage(0)
MyQuest.Start()
expectInt(MyQuest.GetStage(), to, beEqualTo, 10)
MyQuest.Stop()
MyQuest.SetStage(0)
endFunction
Here is the same test suite, but written a little differently. We use beforeEach and afterEach to wrap up our set-up code so our specs only contain the parts important to the feature under test.
function TestSuites()
describe("Story quest", storyQuestSuite())
endFunction
function storyQuestSuite()
it("should give the player the power sword when the quest starts", powerSwordTest())
it("should make sure that the NPC alias is filled when the quest starts", aliasCheckTest())
it("should make sure the stage gets set to 10 after the quest starts", stageCheckTest())
endFunction
function beforeEach()
if MyQuest.IsRunning()
MyQuest.Stop()
endif
QuestAlias.Clear()
MyQuest.SetStage(0)
endFunction
function afterEach()
MyQuest.Stop()
QuestAlias.Clear()
MyQuest.SetStage(0)
int power_sword_count = Game.GetPlayer().GetItemCount(PowerSword)
if power_sword_count > 0
Game.GetPlayer().RemoveItem(PowerSword, power_sword_count)
endif
endFunction
function powerSwordTest()
MyQuest.Start()
expectInt(Game.GetPlayer().GetItemCount(PowerSword), to, beGreaterThanOrEqualTo, 1)
endFunction
function aliasCheckTest()
MyQuest.Start()
expectRef(QuestAlias.GetActorRef(), notTo, beNone)
endFunction
function stageCheckTest()
MyQuest.Start()
expectInt(MyQuest.GetStage(), to, beEqualTo, 10)
endFunction
There is also beforeAll and afterAll functions available. Like the names imply, beforeAll will run once before all test cases (and also before any beforeEach functions, if defined) and afterAll runs after all specs have completed (and after the last afterEach function has run).
- Because of the way Lilac is implemented,
beforeEachandafterEachare called one extra time after every test case has completed. So, they will be called back to back a final time, with no test case. Make sure that nothing bad happens if they are called without a test in between. If your tests are decoupled from each other adequately, this shouldn't be a problem. - You can't have different
beforeEach,afterEach,beforeAll, orafterAllbehavior depending on which test suite you're in. They apply for every single test case in every suite in a test file. (You can't trick it by using different states for each suite, either.)
If you need suite-specific set-up or tear-down code, write your own functions to do this and call them at the top / bottom of your test cases yourself, like so.
function TestSuites()
describe("A suite", suiteA())
describe("Another suite", suiteB())
endFunction
function suiteA()
it("should do stuff", testDoStuff()
it("should do other stuff", testDoOtherStuff()
endFunction
function suiteB()
it("should drive to the store", testDriveToStore()
it("should do a backflip", testDoABackflip()
endFunction
function beforeEach_suiteA()
; Stuff to set up each test in suite A
endFunction
function afterEach_suiteA()
; Stuff to tear down each test in suite A
endFunction
function beforeEach_suiteB()
; Stuff to set up each test in suite B
endFunction
function afterEach_suiteB()
; Stuff to tear down each test in suite B
endFunction
function testDoStuff()
beforeEach_suiteA()
; Test logic
afterEach_suiteA()
endFunction
function testDoOtherStuff()
beforeEach_suiteA()
; Test logic
afterEach_suiteA()
endFunction
function testDriveToStore()
beforeEach_suiteB()
; Test logic
afterEach_suiteB()
endFunction
function testDoABackflip()
beforeEach_suiteB()
; Test logic
afterEach_suiteB()
endFunction