Functional testing of web applications with Spock

Một phần của tài liệu Manning java testing with spock (Trang 237 - 243)

The previous section covered functional tests for back-end Java applications that aren’t interactive. This section shows you how to test front-end applications that sport a web interface accessible via the browser.

For these kinds of tests, you need a way to control the browser and replicate the actions (for example, fill forms or click buttons) that a human user typically performs.

Spock doesn’t have built-in support for this and instead collaborates with Geb, the Groovy browser automation library.

7.4.1 Browser automation with Geb

Geb is a library that provides a Groovy abstraction on top of the popular Selenium/

WebDriver18 framework for automating a browser. If you’ve worked with Selenium, you already know what Geb does. What Geb brings to the table is excellent integration19

18You can learn more about the Selenium suite of tools at www.seleniumhq.org/.

19Geb is written by Luke Daley, who is also a Spock committer.

Performs a POST call on the /products endpoint

213 Functional testing of web applications with Spock

with Spock and a jQuery-like language20 for accessing web page content. If you already know jQuery (or any other similar CSS selector syntax), Geb will be familiar to you.

As a quick example, if you want to examine the text for the h2 header in a web page, Geb allows you to write the following:

$("h2").text()

If you want to click the button with an IDmyButton, Geb offers you this:

$("#myButton").click()

With Geb, you reuse your knowledge of jQuery. If you’re not familiar with jQuery, you need to examine its documentation, and especially the part for CSS selectors, in order to fully use Geb.

7.4.2 The example web application

The application you’ll test with Spock and Geb is a simple web interface over the ware- house manager you’ve seen in the previous examples. Figure 7.10 shows a sample screen from this application.

The code uses Spring MVC, but in a similar manner to the REST tests, the implementa- tion technology doesn’t matter. Geb interacts with only the final web page and doesn't care about the underlying technology. You could write Spock/Geb tests for a PHP application, using the same CSS selectors.

20You can learn more about jQuery at https://jquery.com/.

Figure 7.10 Web interface that will be used for Spock tests

7.4.3 Spock and Geb: a match made in heaven

Let's start with a simple example of Spock and Geb together. As a first test, you’ll verify the title of the first page of the application. Figure 7.11 shows the expected result.

The next listing provides the Geb specification that tests this.

class HomePageSpec extends GebSpec { def "Trivial Geb test for homepage"() {

when: "I go to homepage"

Browser.drive {

go "http://localhost:8080/web-ui-example/index.html"

}

then: "First page should load"

title == "Spock/Geb Web example"

} }

The most important thing to notice in listing 7.10 is that the test class extends the GebSpec class and not the Spock Specification, as shown in all examples so far. This is essential so that Geb methods and objects are available inside the Spock methods.

After this is done, you use the Browser object to load the first page of the applica- tion. Finally, you examine the title object. This object is an implicit one offered by Geb and always represents the HTML title of the current HTML page. It doesn’t follow the jQuery pattern because it’s not part of the content of the page.

Listing 7.10 Using Geb and Spock together

Figure 7.11 Expected result for title page is the string "Spock/Geb Web example"

Spock specification class that makes Geb facilities available

Orders the test browser to load a specific URL

Tests the title of the application

215 Functional testing of web applications with Spock

To see the jQuery syntax of Geb, let's modify the test to look at the page content in addition to the page title. You’ll test an HTML header (h1) and also make sure that the first tab of the user interface is selected. Figure 7.12 shows the expected result.

The updated Spock test verifies the title as before and reads the page content to make sure that the expected text is present on the page (see the following listing).

def "Trivial Geb test for homepage -header check"() { when: "I go to homepage"

Browser.drive {

go "http://localhost:8080/web-ui-example/index.html"

}

then: "First page should load"

title == "Spock/Geb Web example"

$("h1").text() == "Java Testing with Spock - Sample code"

$(".active").text() == "Welcome"

}

Will this test launch a browser?

Remember that Geb is an abstraction over Selenium/WebDriver, so it supports what- ever browser implementations are already there. In the source code of the book, the default browser is Firefox, so if you run this test, a new Firefox instance will be launched on your computer and you’ll see it react automatically to the test definitions. You can use other browsers or even browser emulators (such as Phantom.js, http://phantom js.org/) as other options. Consult the Geb documentation on how to achieve this.

Listing 7.11 Using Geb to access page content

Figure 7.12 HTML content that will be verified by the Geb test.

You’ll verify the h1 element and the “active”

CSS class.

Launches the first page of the application in the browser Examines the

title of the page

Examines the content of the h1 element Examines the

content of the element with the

"active" CSS class

This listing demonstrates the jQuery-like style of Geb for accessing page content. The last two lines in the then: block will be examined by Geb against the HTML content found in the browser. The test will fail if the HTML content differs from the expected one.

7.4.4 Using Geb to interact with a web page

For a more useful example than simple page loading, let’s see how to emulate user actions on a web page. The sample application contains a form, shown in figure 7.13, that allows the user to create a new product. An HTML form is used to define the name of the product and its price. After the user submits the form, a success message appears.

You’ll create a test that navigates to the form page, inputs the name of the product, submits the form, and verifies the success message (not shown in figure 7.13). The code is shown in the next listing.

@Stepwise class AddProductGebSpec extends GebSpec { def "Navigation to page"() {

when: "I go to the new product page"

Browser.drive {

go "http://localhost:8080/web-ui-example/add- product.html"

}

then: "the form should load"

$(".col1").$("h2").text() == "New Product details"

}

Listing 7.12 Using Geb to submit HTML forms

Figure 7.13 Details of an HTML form. You’ll fill the input fields and submit it programmatically.

Ensures that test methods will run in order

This Spock test has access to Geb facilities by extending GebSpec.

Navigates to the page with the HTML form Verifies that

browser is in correct page

217 Functional testing of web applications with Spock

def "Creation of new product"() { when: "I fill in product details"

$("input[name='productName']").value("Bravia TV") $("#createProductButton").click() then: "I should see a success message"

$(".ok").text() == "You added new product named: Bravia TV."

} }

This listing has several important points. First, you use the @Stepwise annotation again. The reason for this is that the test contains two methods. The first one navigates to the HTML form page, and the second submits the form. If the first fails for some reason (for example, the application isn’t up), there’s no point in running the second method. The @Stepwise annotation ensures that the form won’t be submitted if its page can’t be found.

Second, in order to verify the formed page, you use an HTML element chain:

$(".col1").$("h2").text() == "New Product details"

This line means, “Locate an element with the CSS class col1 and then search for a child that is a header of level 2. This header should contain the text New product details.”

Next, the form is submitted with the following two lines:

$("input[name='productName']").value("Bravia TV")

$("#createProductButton").click()

The first line means, “Locate an HTML element of type input that has a name attribute with value productName. Then fill in the text Bravia TV.” The second line says, “Find an element with ID createProductButton. Then click it (assuming that it’s a button).”

Running the test launches the Firefox browser on your computer, and you’ll see it perform these actions in real time. The final line in the then: block locates an ele- ment with CSS class ok and checks its text (in the example application, it’s a span HTML element).

I hope that this example gives you an idea of the capabilities of Geb. I’ve barely scratched the surface of all the possible use cases. Check the official Geb documenta- tion (http://www.gebish.org/manual/current/) for more details. Make sure not to miss the Page Objects pattern21 for reducing22 duplicated code among tests and the ability to get screenshots23 while a test runs. The previous tests shown are contrived examples so that you get a feel for Geb’s capabilities. In a real application, you’d orga- nize all your Spock tests around pages to make them resilient to GUI changes.

21http://docs.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern

22www.gebish.org/pages

23http://www.gebish.org/manual/current/

Enters text into an input field

Activates the form button Verifies the

success message shown on page

As an exercise, write Geb tests for the page of the application that lists existing prod- ucts. Write a test that also fills in the price field of the form and then goes to the inven- tory page and verifies that the product is correctly inserted with the correct price.

As another exercise, modify your Geb tests to use Page objects instead of exposing HTML elements inside them.

Một phần của tài liệu Manning java testing with spock (Trang 237 - 243)

Tải bản đầy đủ (PDF)

(306 trang)