
In software development, acceptance criteria is a way via which a client communicates their expectations to engineering team. Also, it acts as a list of conditions upon completion of which a software/app is marked as complete.
Since acceptance criteria is an important part of software development, it becomes important to determine that the acceptance criteria is met by the software or not. This sub-discipline of software development where a software is tested against the acceptance criteria is called, Acceptance Testing. In other terms, acceptance testing is a type of black-box testing performed on a software prior to it’s delivery.
In this blog, we’re going to look at Cucumber as a tool for writing acceptance tests of a Lagom microservice. The reason behind integrating Cucumber with Lagom is that Lagom helps us decompose our legacy monolith and build, test, and deploy entire systems of Reactive microservices. Since our monolith application is being decomposed, we need to make sure that it meets the business acceptance criteria. So, in order to do that in an automated fashion, we have selected Cucumber.
Add Cucumber to the POM
Now let’s see how to achieve this integration via an example:
For Maven:
<dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>4.2.6</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit</artifactId> <version>4.2.6</version> <scope>test</scope> </dependency>
Get Ready to Write a Scenario
While doing Acceptance Testing with Cucumber, concrete examples are used to specify what the Application is expected to do. For this Scenario(s) are created in Cucumber which are defined in .feature
files, stored under src/test/resources/<package-name>
(directory).
One such scenario, for our Lagom application, would be to Get Menu if it is available in a restaurant.
For this create get-menu.feature
file under src/test/resources/com/knoldus/lagom/sample/restaurant/menu/impl
directory:
Feature: Can I Get Menu?
User wants to know whether he/she can Get Menu
Scenario: User can Get Menu
Given Restaurant has Menu
When User asks for Menu
Then User should Get Menu
Turn Scenario into Concrete Actions
After defining the scenario, the next step is to convert it in to code:
RunCucumberTest.java
package com.knoldus.lagom.sample.restaurant.menu.impl; import cucumber.api.CucumberOptions; import cucumber.api.junit.Cucumber; import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions(plugin = {"pretty"}) public class RunCucumberTest { }
Stepdefs.java
package com.knoldus.lagom.sample.restaurant.menu.impl; import com.knoldus.lagom.sample.restaurant.menu.api.Item; import com.knoldus.lagom.sample.restaurant.menu.api.MenuService; import com.lightbend.lagom.javadsl.testkit.ServiceTest; import cucumber.api.java.After; import cucumber.api.java.Before; import cucumber.api.java.en.Given; import cucumber.api.java.en.Then; import cucumber.api.java.en.When; import org.junit.Assert; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class Stepdefs { private static final long TIMEOUT = 10L; private static ServiceTest.TestServer server; private static MenuService service; private static List<String> menu; @Before public static void setUp() { server = ServiceTest.startServer(ServiceTest.defaultSetup().withCassandra()); service = server.client(MenuServiceImpl.class); } @Given("Restaurant has Menu") public void restaurant_has_Menu() throws InterruptedException, ExecutionException, TimeoutException { // Write code here that turns the phrase above into concrete actions service.addItem().invoke(Item.builder().name("item").build()).toCompletableFuture() .get(TIMEOUT, TimeUnit.SECONDS); //Waiting for data to get added in DB. Thread.sleep(5000L); } @When("User asks for Menu") public void user_asks_for_Menu() throws InterruptedException, ExecutionException, TimeoutException { // Write code here that turns the phrase above into concrete actions menu = service.getMenu().invoke().toCompletableFuture().get(TIMEOUT, TimeUnit.SECONDS); } @Then("User should Get Menu") public void user_should_Get_Menu() { // Write code here that turns the phrase above into concrete actions Assert.assertTrue(menu.contains("item")); } @After public static void afterClass() { if (server != null) { server.stop(); server = null; } } }
Execute Scenario
The last step is to execute the scenario and see if it passes or not:
mvn clean test
Output:
Feature: Can I Get Menu?
User wants to know whether he/she can Get MenuScenario: User can Get Menu # com/knoldus/lagom/sample/restaurant/menu/impl/get-menu.feature:4
Given Restaurant has Menu # Stepdefs.restaurant_has_Menu()
When User asks for Menu # Stepdefs.user_asks_for_Menu()
Then User should Get Menu # Stepdefs.user_should_Get_Menu()1 Scenarios (1 passed)
3 Steps (3 passed)
1m4.902s
Now we have got our first scenario created in Cucumber for a Lagom micro-service.
So, I hope you all found this article useful in terms of Acceptance Testing of a Lagom Micro-service. If anyone wants to try the whole example, then the code can be downloaded from here – Lagom Cucumber Example.