# How to write test cases for a command ?

Refer Lottery Example Command Testing to see how testcases are written.

In the lottery project, we have a command called create which is used to create a lottery for a certain amount. A lottery can't be created twice with a same name. When the lottery is created, LotteryCreated event is raised. If attempted to create a lottery with a name that already exists,lotteryMustNotExist pre condition will fail.

Let's take the example of testcases written in lottery for 'create' command and try to understand what is happenning

  • We write the testcases in CreateCommandTestSuite.scala file .

  • We write two types of testcases. positive test case and negative test case (denoted by 'ptest' and 'ntest' respectively). Positive test case is written expecting an output when correct input is provided and negative test case is written to test how the command handles wrong inputs.

/*
 1. test(<name>, <tag>, <positive/negative testcase>)
 2. ptest: positive test case
 3. ntest: negative test case
*/ 
test("create first lottery", Tag("create"), ptest) {
  /* 
    As we dont want to avoid any conflicts between data of other commands, we start 
    with an empty database.
    We drop the database by saying 'LotteryWriter().drop()'
  */
    LotteryWriter().drop()
    grab[CreateCommandFixture] // Then we grab the command fixture by saying 'grab[CreateCommandFixture]'.
      .given() // In 'given()' we specify the state of the application while executing the command.
      .when(Input("TestLottery", 200)) // We specify the input for the command inside 'when()'.
      .expectEventRaised(EventRaised(LotteryCreated("TestLottery", 200))) // As it is a ptest and the command should raise an event for the given input, we write 'expectEventRaised(EventRaised(event))'  
}


test("create new lottery with same name", Tag("duplicate"), ntest) {
    LotteryWriter().drop()
    grab[CreateCommandFixture]
      .given(LotteryCreated("TestLottery", 100)) //It is given that there exists a lottery with name 'TestLottery' and 100 as amount.
      .when(Input("TestLottery", 200)) //As it is given that the lottery already exists, a pre condition should fail for this input
      .expectPreFail("lotteryMustNotExist") //As it is a ntest and we expect a pre condition to fail, we write 'expectPreFail()'
}
  • To run a test case, go to the module: 'project moduleName'
  • $testOnly *ModuleName* -- -n "tag" - to run only the test case with the given tag.
[Lottery] $ project LotteryDomain
[info] Set current project to LotteryDomain (in build file:/Users/vishnuv/metastay/lottery/)
[LotteryDomain] testOnly *CreateCommandTestSuite -- -n "create"
[info] CreateCommandTestSuite:
[info] - create first lottery
[info] ScalaTest
[info] Run completed in 1 second, 271 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 3 s, completed 26 Jun, 2019 12:42:23 PM
  • test - to run all the test cases.
[LotteryDomain] test
[info] AddParticipantCommandTestSuite:
[info] RunCommandTestSuite:
[info] - test1
[info] CreateCommandTestSuite:
[info] - create first lottery
[info] - create new lottery with same name
[info] LotteryDomainLogicTestSuite:
[info] - test1
[info] LotteryDomainTestSuite:
[info] - lottery
[info] ScalaTest
[info] Run completed in 1 second, 654 milliseconds.
[info] Total number of tests run: 5
[info] Suites: completed 5, aborted 0
[info] Tests: succeeded 5, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 5, Failed 0, Errors 0, Passed 5
[success] Total time: 2 s, completed 26 Jun, 2019 12:42:47 PM