Beliebte Suchanfragen

Cloud Native

DevOps

IT-Security

Agile Methoden

Java

//

Getting Started with Zucchini

24.7.2014 | 8 minutes of reading time

What is Zucchini?

Zucchini is a new testing framework that uses a BDD-style domain-specific language (DSL). One of its focus areas is simplifying acceptance tests written with Selenium. It is not a replacement for JBehave or the Robot Framework, as you will see later on. This guide will give you a glimpse of Zucchini’s concepts by describing an example step by step.

Your First Zucchini Test

We are starting with this simple test class:

1public class GettingStarted extends CommonStatements {
2    @Test
3    public void testCodecentricSearch() {
4        given("I am on codecentric.de")
5            .when("I type \"codecentric\" into the search box")
6            .andWhen("I submit the search")
7            .then("I see \"codecentric\" on the page")
8            .end();
9    }
10}

This looks pretty easy, doesn’t it? But let’s examine this test for a moment:

  • This is obviously some kind of test. @Test suggests that this is a JUnit test, and that is indeed correct.
  • It seems like there is some kind of domain-specific language involved: given().when().andWhen().then().end().
  • "I am on codecentric.de" looks like some kind of initial situation.
  • "I type \"codecentric\" into the search box" and "I submit the search box" look like interactions that a user has with a website.
  • "I see \"codecentric\" on the page" looks like an expectation.

If you’ve made it so far, you already know 90% of the important stuff. But wait, we missed something, didn’t we? How does the test know what to do with these statements? Is there a complex language I have to learn before? And what is this CommonStatements class doing there? Okay, to be honest: I have held back some information. First of all, no, you don’t have to learn a new language. The statements in this test are placeholders for instructions that I will show you in a moment. And yes, CommonStatements plays a big role. But most importantly: This is a real test and it works perfectly. It will do what you expect it will do and there is missing in this class. The next section will describe the magic behind those statements.

The CommonStatements class

Magic

The previous section contained a simple test that navigates to codecentric.de, types “codecentric” into the search box, submits the search box and expects “codecentric” to be somewhere on the page – for example, as part of search results – afterwards. There seemed to be some magic involved since we have already ruled out that there is a complex language you have to learn. So what is the magic inside CommonStatements? I am sorry to disappoint you but there is no magic at all. This is most of the part that I have held back before:

1public class CommonStatements {
2    @Rule
3    public WebFactRule onCodecentricRule = new WebFactRule(
4        "I am on codecentric.de",
5        onPage(url("http://www.codecentric.de"))
6    );
7 
8    @Rule
9    public WebStepRule searchCodecentricRule = new WebStepRule(
10        "I type \"codecentric\" into the search box",
11        type("codecentric").into(By.name("s"))
12    );
13 
14    @Rule
15    public WebStepRule submitSearchRule = new WebStepRule(
16        "I submit the search",
17        submit(By.name("s"))
18    );
19 
20    @Rule
21    public WebResultRule seeCodecentricOnPageRule = new WebResultRule(
22        "I see \"codecentric\" on the page",
23        see("codecentric")
24    );
25 
26    @Rule
27    public WebDriverExecutorRule webDriverExecutorRule = new WebDriverExecutorRule(
28        new ChromeDriverProvider()
29    );
30}

Okay, now I’ve lost you. Let’s take baby steps towards becoming a Zucchini master.

Facts

We will start with the following code snippet as a first step:

1@Rule
2public WebFactRule onCodecentricRule = new WebFactRule(
3    "I am on codecentric.de",
4    onPage(url("http://www.codecentric.de"))
5);

At first, you will notice that the statement that we have seen in our test case is part of a JUnit @Rule. I will not talk about JUnit @Rules here. If you don’t already know about this concept, you might want to go to the documentation before you continue.

The second part of the so called WebFactRule is onPage(url("http://www.codecentric.de")). Both, onPage() and url() are statically imported methods.

onPage() returns a WebFact. Basically, a fact is something you expect to be part of the initial state of a test. Actually, you don’t want to test facts. You take them for granted. Of course, Zucchini will detect if facts are broken and your test will fail if they are. If you have worked with Behavior Driven Development (BDD) before, you’re already familiar with Given, When, and Then. Zucchini calls atomic statements describing the initial state (Given) facts. Now, onPage() does not return Fact but WebFact. Web facts are specialized facts for web testing purposes. WebFact is just the interface for all types of web-specialized facts. The actual type of the object returned by onPage() is OnPageFact. All fact implementations describe how Zucchini can establish them. The OnPageFact knows how to open a specific page.

So, why do you need url(), you might ask. OnPageFact is more powerful than you need to know for the moment (in case you are curious: it supports Page Objects ). The OnPageFact does not work on URLs directly but on something like a wrapper. For the sake of simplicity, let’s say url() takes a URL and wraps it in an object. I guess, we can take a step back and look at the previous code snippet again:

  • The WebFactRule is a JUnit @Rule that registers a fact.
  • The example above uses "I am on codecentric.de" as a name – no magic involved!
  • The fact of this example is able to open http://www.codecentric.de in a browser.

Steps

While growing up and learning more, baby steps become bigger. So let’s take a bigger code snippet:

1@Rule
2public WebStepRule searchCodecentricRule = new WebStepRule(
3    "I type \"codecentric\" into the search box",
4    type("codecentric").into(By.name("s"))
5);
6 
7@Rule
8public WebStepRule submitSearchRule = new WebStepRule(
9    "I submit the search",
10    submit(By.name("s"))
11);

We have seen facts in the previous section. Now, we will introduce steps. While facts describe the initial state of the test, steps describe what you want to do once the initial state has been established.

What’s new? Actually, not much. Zucchini provides many useful methods that you can import statically to interact with pages, for example:

  • type(keys) types the given keys (text or a key combination) on the page,
  • type(keys).into(element) types the given keys into an element (e.g. a text input, text area, WYSIWYG editor, …),
  • select(element).index(index) selects the option with the index of a select element,
  • click(element) clicks on an element,
  • submit(element) submits an element, and many more.

Most of the web steps work on elements. These elements are described using Selenium’s By, for example:

  • By.id("html-element-id") describes the HTML element with the id attribute value html-element-id,
  • By.name("input-name") describes the HTML element with the name attribute value input-name,

Note: It is possible to create By locators that locate multiple elements. That’s perfectly fine. Sometimes you want to do something with multiple elements.

For more information on locating elements, please take a look at the Selenium WebDriver documentation.

By now, you should have deciphered the two rules above. However, I will summarize what you most likely already know:

  • Two new steps have been registered.
  • The first step is called "I type \"codecentric\" into the search box" and it simply types the text “codecentric” into a search box.
  • The second step is called "I submit the search" and it simply submits the search box (similar to hitting enter while still focussing the box).

Results

We are getting close to the end of this guide. By now, you should have figured out how to register facts that define the initial state and steps that describe how you want to interact with a page. This section will show you how you can check for page characteristics.

1@Rule
2public WebResultRule seeCodecentricOnPageRule = new WebResultRule(
3    "I see \"codecentric\" on the page",
4    see("codecentric")
5);

A WebResult is a web-specific Result that checks whether the page state looks like you’d expect it to look. Zucchini provides some basic implementations, for example:

  • see(text) checks whether the text is present on the page,
  • input(element).isDisabled() checks whether the element is disabled.

The @Rule above can be described as follows:

  • A new result is registered.
  • The new result is called "I see \"codecentric\" on the page".
  • The result expects that “codecentric” is shown.

Now you know what facts, steps, and results are and you know how you can define them. Since Zucchini uses plain Java, you will be able to use all of your IDE’s auto-completion features. You don’t need an additional plug-in for your IDE or additional IDE configuration.

Executing Tests

The last part of the CommonStatements class is this:

1@Rule
2public WebDriverExecutorRule webDriverExecutorRule = new WebDriverExecutorRule(
3    new ChromeDriverProvider()
4);

This guide focusses on Zucchini’s web components. You can use Zucchini for other types of tests but that is a whole other story. I tell you this because different types of tests require different types of Executors.

The @Rule above registers a web-specific Executor that uses the Selenium WebDriver API internally. Selenium can run in multiple browsers so we need to tell the executor which browser to use. This example uses Chrome. You might want to use HtmlUnit instead for headless testing. I’ll leave you to it.

Dig Deeper

This short guide introduced parts of Zucchini which is a lean testing framework that uses a BDD-style DSL. You have learned how to write simple Zucchini web tests and I have shown you the basic concepts behind Zucchini. Here are some suggestions in case you want to dig deeper into Zucchini:

share post

Likes

0

//

More articles in this subject area

Discover exciting further topics and let the codecentric world inspire you.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.