Verify web page content without a web server

Một phần của tài liệu Manning JUnit recipes practical methods for program (Trang 522 - 525)

Problem

You want to verify the content of a web page using HtmlUnit, rather than XPath- based assertions, but without running a web server.

Background

You have used HtmlUnit in End-to-End Tests, and you like the way it works. Its cus- tomized assertion library is designed specifically for analyzing web pages, making it an ideal tool to use when testing all kinds of web pages without a web server: static web pages, rendered Velocity templates, possibly even rendered JSPs. The problem is that, out of the box, HtmlUnit is coupled to its HTTP client: there is no way to create an HtmlPage object without retrieving it through a WebConnection, so you cannot use HtmlUnit unless you test against a live web server or web container.

Recipe

Out of the box, HtmlUnit expects to retrieve web pages from a remote server, but with only a few lines of code it is possible to load web pages from the file system.

Listing 12.17 shows an example of how to use that code.18

18The code the test is using—FileSystemWebResponse and FileSystemWebConnection—is part of Diasparsoft Toolkit, and should one day be submitted as a patch to HtmlUnit.

492 CHAPTER 12

Testing web components

public void testContent() throws Exception { URL loginPageUrl =

new URL("http://localhost/coffeeShop/login.html");

File loginPageFile =

new File(webContentDirectory, "login.html");

WebClient webClient = new WebClient();

FileSystemWebResponse webResponse =

new FileSystemWebResponse(loginPageUrl, loginPageFile);

webResponse.setContentType("text/html");

FileSystemWebConnection fileSystemWebConnection = new FileSystemWebConnection(webClient);

fileSystemWebConnection.setResponse(webResponse);

webClient.setWebConnection(fileSystemWebConnection);

HtmlPage loginPage =

(HtmlPage) webClient.getPage(loginPageUrl);

assertEquals("Login", loginPage.getTitleText());

assertTrue(

loginPage.asText().indexOf(

"Enter your user name and password") >= 0);

HtmlForm loginForm = loginPage.getFormByName("loginForm");

assertNotNull(loginForm);

assertEquals("/coffeeShop", loginForm.getActionAttribute());

assertTrue(

"post".equalsIgnoreCase(loginForm.getMethodAttribute()));

HtmlInput usernameInput = loginForm.getInputByName("username");

assertNotNull(usernameInput);

assertEquals(

12,

Integer.parseInt(usernameInput.getSizeAttribute()));

assertTrue(usernameInput instanceof HtmlTextInput);

assertEquals("", usernameInput.getValueAttribute());

HtmlInput passwordInput = loginForm.getInputByName("password");

assertNotNull(passwordInput);

assertTrue(passwordInput instanceof HtmlPasswordInput);

assertEquals(

12,

Integer.parseInt(passwordInput.getSizeAttribute()));

assertEquals("", passwordInput.getValueAttribute());

HtmlInput loginInput = loginForm.getInputByName("login");

assertNotNull(loginInput);

assertTrue(loginInput instanceof HtmlSubmitInput);

assertEquals("Login", loginInput.getValueAttribute());

}

Listing 12.17 Loading web pages from the file system with FileSystemWebResponse

Just a label here Point to the page on the file system

Set up a mock WebResponse from the file system

Register the mock WebResponse with the WebClient Ask HtmlUnit to create the HtmlPage

Better than checking the

“type” attribute Prime a mock Web- Connection with the mock WebResponse

493 Verify web page content

without a web server

The instanceof check in this code bears some explanation. Rather than verify the value of the type attribute, we recommend using instanceof to verify the input tag’s type without resorting to a case-insensitive string comparison. The alterna- tive is to write this assertion:

assertTrue("text".equalsIgnoreCase(myInput.getTypeAttribute());

If you try to use assertEquals(), you run the risk of typing TEXT in the web page and having the test fail while the browser is satisfied. This makes the test unneces- sarily brittle, adds the risk of “false failures” and those are bad things. You have enough problems to handle without creating more for yourself!

Discussion

This technique works very well for static web pages, but what about dynamic ones?

You cannot simply retrieve them from the file system, because as page templates (JSPs or Velocity templates) they need to be merged with some set of data to pro- duce a final result. No need to worry, though: just render the page, then obtain its content as either an InputStream or a String. If you can do this, then HtmlUnit can create an HtmlPage object from it, and that is all you need to be able to use its HTML assertion library in your tests.

If you are using JSPs, apply the technique in recipe 12.3, after which point you will have the rendered web page as a String. You can create an InputStream from that String using HtmlUnit’s utility method TextUtil.toInputStream(String). You can then create an InputStreamWebResponse and the corresponding Input- StreamWebConnection, substituting them in this recipe’s sample code, like so:19

FileInputStream webPageAsInputStream = new FileInputStream(loginPageFile);

TextUtil.toInputStream("Web page content as a string");

WebClient webClient = new WebClient();

InputStreamWebConnection inputStreamWebConnection = new InputStreamWebConnection(webClient);

InputStreamWebResponse webResponse = new InputStreamWebResponse(

loginPageUrl,

webPageAsInputStream);

webResponse.setContentType("text/html");

inputStreamWebConnection.setResponse(webResponse);

19These classes are also part of Diasparsoft Toolkit.

494 CHAPTER 12

Testing web components

webClient.setWebConnection(inputStreamWebConnection);

HtmlPage loginPage = (HtmlPage) webClient.getPage(loginPageUrl);

After this point, make the same kinds of assertions that we made in our example.

If you are using Velocity templates, then apply the technique we describe in recipe 12.4, “Test rendering a Velocity template.” This involves writing the result- ing web page to a String, from which point you can use the same code as we have just provided to obtain an HtmlPage.

No matter how you render a web page—from the file system, through a tem- plate engine, some other way—if you can get either an InputStream or a String with that web page’s contents, you can use HtmlUnit to verify its structure and contents. To verify its look and feel, however, generally requires human interven- tion, at least at first. See recipe 12.3 for an example of comparing a rendered dynamic web page against a Gold Master. This technique ensures that the page looks right, in addition to merely having all the right content.

Related

■ 12.3—Test rendering a JavaServer Page

■ 12.4—Test rendering a Velocity template

■ Chapter 9—Testing and XML

■ HtmlUnit (http://HtmlUnit.sourceforge.net)

Một phần của tài liệu Manning JUnit recipes practical methods for program (Trang 522 - 525)

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

(753 trang)