5.7 Testing HTML Tables

5.7.1 Problem

You want to test the contents of one or more HTML tables.

5.7.2 Solution

Use com.meterware.httpunit.WebTable and com.meterware.httpunit.TableCell to analyze the content of tables in your HTML pages.

5.7.3 Discussion

HttpUnit provides a simple API for parsing HTML and obtaining tables, cells, and cell content. Figure 5-1 shows a sample web page for the code shown in this recipe.

Figure 5-1. Sample HTML tables
figs/jexp_0501.gif

Example 5-2 demonstrates how you can test the content of the top table. In this example, the table is located based on the text found within its first cell using the WebResponse.getTableStartingWith( ) method.

Example 5-2. Simple table testing
    public void testPersonTable(  ) throws Exception {
        WebConversation webConversation = new WebConversation(  );
        WebResponse response = webConversation.getResponse(
                "http://localhost:8080/news/sampleTable.html");

        // get the HTML table with 'First Name' as the text of its
        // first non-blank cell
        WebTable table = response.getTableStartingWith("First Name");
        assertEquals("column count", 2, table.getColumnCount(  ));
        assertEquals("row count", 3, table.getRowCount(  ));

        // get the cell at row 2, column 0
        TableCell cell = table.getTableCell(2, 0);
        assertEquals("cell text", "Tanner", cell.asText(  ));
    }

Once the WebTable object is located, the test uses various methods on the WebTable class to obtain the number of rows and columns, as well as to locate a TableCell at a particular position.

While this approach is fine for simple tables, it tends to be too fragile. People may redesign page layout frequently, and this sort of test is sensitive to things like exact row and column positions. A better approach, shown in Example 5-3, is to assign identifiers to critical portions of your tables.

Example 5-3. Testing a table with identifiers
    public void testAccountTable(  ) throws Exception {
        WebConversation webConversation = new WebConversation(  );
        WebResponse response = webConversation.getResponse(
                "http://localhost:8080/news/sampleTable.html");

        WebTable accountTable = response.getTableWithID("accountInfoTbl");
        assertNotNull("account table", accountTable);

        // get the checking account number
        TableCell checkingCell =
                accountTable.getTableCellWithID("checkingAcctNbr");
        assertEquals("Checking account number",
                "12345", checkingCell.asText(  ));
    }

Now, by locating identifiers, you can rearrange your table layout as you see fit. Unless you change the identifiers, your tests continue functioning. Example 5-4 shows the HTML for the table being tested here, so you can see what the id tag looks like.

Example 5-4. HTML for table using identifiers
<table id="accountInfoTbl" border="1">
  <tr id="headingRow">
    <th>Account Type</th><th>Number</th><th>Balance</th>
  </tr>

  <tr>
    <td>Checking</td>
    <td id="checkingAcctNbr">12345</td>
    <td id="checkingAcctBal">$5,436.00</td>
  </tr>

  <tr>
    <td>Savings</td>
    <td id="savingsAcctNbr">54321</td>
    <td id="savingsAcctBal">$3,698.04</td>
  </tr>
</table>

If you are concerned about the larger HTML pages required by the ID attributes, consider writing a script to strip out all of the identifiers after your tests have all passed.

5.7.4 See Also

Recipe 5.6 discusses testable HTML.