Cuke in Space!, this project aiming to bring cucumber BDD framework to Arquillian. The goal is simple: keep the strength of the Behavior Driven Development adding to it the strength of Arquillian (portable test writing between containers, deployment control, multi-containers tests…).
Since it is close to a release this post shows important new features you’ll get with it.
If you never read about the project here in two words how it works:
- you define features (see next snippet) in a resource
- you create a class (arquillian test class) matching the snipet
Here is a feature:
Feature: Eat Cukes Scenario: Eating 4 cukes Given I have a belly When I eat 4 cukes Then I should have 4 cukes in my belly
And here a java Cuke in Space! test:
@RunWith(ArquillianCucumber.class) public class CukesInBellyWithClassPathScanningFeatureTest { @Deployment public static Archive<?> createDeployment() { return create(WebArchive.class) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClass(Belly.class); } @Inject private Belly belly; @When("^I eat (\\d+) cukes$") public void eatCukes(int cukes) { belly.setCukes(cukes); } @Given("^I have a belly$") public void setUpBelly() { belly = new Belly(); } @Then("^I should have (\\d+) cukes in my belly$") public void shouldHaveThisMany(int cukes) { assertEquals(cukes, belly.getCukes()); } }
There are two main differences with a standard Arquillian test:
- the runner is ArquillianCucumber and not Arquillian (to be able to support next point)
- the methods are not @Test methods but cucumber methods matching the feature lines
This is the basis of a Cuke in Space! test. You’ll find all the details in the github README. In three words you can get a report of your tests, configure where are the features (you can split them in several classes getting arquillian injections), filter tests to run them by tag….
Another new and great feature is the support of scala now.
You basically write a scala singleton (object) for the deployment method of arquillian and a standard scala class for the method matching the features. I like this syntax for several reasons:
- It splits deployment and steps declaration (more readable IMO)
- Methods are step and doesn’t need a method name + an annotation
- Scala language makes real tests quite easier (collection handling in particular)
To use it simply add cucumber-scala dependency with scala-library you want to use. The last one is the scala runtime dependency and the first one provides a nice DSL.
Here is a sample:
object ScalaCukeSpaceTest { @Deployment def archive() = { ShrinkWrap.create(classOf[WebArchive], "cuke-in-space-with-scala.war") .addClass(classOf[ScalaStuff]) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") } } @RunWith(classOf[ArquillianCucumber]) class ScalaCukeSpaceTest extends ScalaDsl with EN { @Inject private [this] var stuff: ScalaStuff = _ private [this] var world: String = _ Given( """^I have a stuff$""") { assertNotNull(stuff) } When( """^I ask the world where stuff is$""") { world = stuff.whereAmI() } Then( """^I get "([^"]*)"$""") { world: String => assertEquals("Scala", world) } }
You can find the whole sample here – note: it uses snapshots at the moment and i supposed you have them locally.