C# – How to Test HTML Output Created by a Class

asp.net-mvcchtmlparsingunit testing

As a learning project, I am trying to create something similar to the WebGrid that comes with ASP.NET MVC. Now this component MyGrid<T> looks like this:

public class MyGrid<T> where T : class
{
  public MyGrid(IEnumerable<T> dataSource) { ... }
  public bool AutoGenerateColumns { get; set; }
  public MvcHtmlString HtmlMarkup { get; }
  // some more stuff
}

I have so far written some tests that test basic functionality of the grid, as well as check for some thrown exceptions. But I wonder how I should best test for the correct output, as it comes as MvcHtmlString. An example of how I checked for an empty grid is the following test:

[TestMethod]
public void AutoGenerateColumnsFalseProducesEmptyTableWhenNoColumnsAreSpecified()
{
  var grid = new MyGrid<object>(new object[] { "a", "b" });
  grid.AutoGenerateColumns = false;
  string markup = grid.HtmlMarkup.ToHtmlString();
  XDocument xdoc = XDocument.Parse(markup);

  XElement table = xdoc.Descendants().First();
  Assert.IsTrue(table.Name == "table");

  // children: thead, tbody, tfoot
  foreach (XElement child in table.Descendants())
  {
    Assert.IsFalse(child.HasElements);
  }
}

This seems quite clunky to me, plus I don't know if using XDocument is a good way to test this here. To create the markup, I use TagBuilder instead.

So to check for an empty grid is not as short/elegant as I'd like it to be. Any tips on how to make this test better are very welcome. But how would I test for more complex stuff, like to check for correct output?

The TagBuilder seems to produce some whitespace, so one way to test would be to strip the output of all whitespace and then compare with a handwritten HTML string. But again, this seems very clunky (and leaves much room for typing errors on my part).

Do you have any suggestions on how to test the (more complex) HTML output for correctness? Is there a more elegant/better way than XDocument to parse the output perhaps?

Best Answer

The more modern approach is to utilize the HTML Agility Pack. The syntax is closer to the dom selections that would be in a JS Library like JQuery.

Here's some examples:

This can also be loaded as a Nuget package.

Related Topic