0 Comments

In Part 1 of this series I demonstrated how QUnit can be used to test JsonResult action methods in ASP.NET MVC applications. Part 2 will take the idea a little further by showing an example of how QUnit can be used to inspect potential user-input areas on your MVC forms and to use those values in tests that will verify the requirements have been met.

The scenario will be a search form that will search a database of people. To use the mindset from a post I made earlier this week, the application will need to meet the following requirements:

  • People will consist of first and last names.
  • The search will need to allow for a free-form text entry field. Each person record whose first or last names contain the string being searched will be returned to the user.

Not too difficult a set of requirements but clearly-enough stated so that tests can be provided. Of course, a stub of functionality will be created to provide the database of people. The code below demonstrates a PersonFactory class that will return instances of the Person class in a generic List.

public class PersonFactory
{
  public static List GetAll()
  {
    List people = new List();
    people.Add(new Person { FirstName = "Al", LastName = "Pacino" });
    people.Add(new Person { FirstName = "Val", LastName = "Kilmer" });
    people.Add(new Person { FirstName = "Robert", LastName = "DeNiro" });
    return people;
  }
}
public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

Next, a controller method is added that will make use of the PersonFactory and return the search results to the client in a JsonResult instance.

public JsonResult FindPerson(string name)
{   List people = PersonFactory.GetAll();   JsonResult result = new JsonResult();   people =   people.FindAll(x => x.FirstName.Contains(name) || x.LastName.Contains(name)).ToList();   result.Data = people;   return result; }

Since the expectation is that the person-searching functionality will be performed from a web page on which a textbox is provided to the user for free-form entry a mock GUI will be created to drive the test itself. The HTML code below provides a form that the tests will use in a moment.

<div class="container">
FindPerson Parameter
</div>

Think of it this way. If a web application needs to first go through a rigid QA process to succeed a checkpoint, what better way to make sure the QA process runs as smoothly as possible by automating the use-cases agreed on by the team in the form of unit tests? The obvious next step is to do the very thing we'd expect a QA person to do - enter some text into the specified text box and perform the search with the expectation that our search would return a result. 

$('#findPersonName').val('Pacino')
  $.getJSON('/Home/FindPerson', { name: $('#findPersonName').val() }, function(data)
  {
    module('FindPerson');
    test('FindPerson with known value for last name returns matching person records', function()
    {
      equals((data.length > 0), true, 'At least one person should return from the search');
    });
  });
  $('#findPersonName').val('Robert')
  $.getJSON('/Home/FindPerson', { name: $('#findPersonName').val() }, function(data)
  {
    module('FindPerson');
    test('FindPerson with known value for first name returns matching person records', function()
    {
      equals((data.length > 0), true, 'At least one person should return from the search');
    });
  });

Of course, any good testing process will test the process's ability to fail gracefully as well. To accomplish that, another string will be entered that logically would always fail to return a result. 

$('#findPersonName').val('NOWAY')
  $.getJSON('/Home/FindPerson', { name: $('#findPersonName').val() }, function(data)
  {
    module('FindPerson');
    test('FindPerson with value not found in list returns no records', function()
    {
      equals((data.length == 0), true, 'No results should be returned from the search');
    });
  });

The HTML output would appear like the screenshot below. 

In this example, QUnit was used to automate the modification of form data and to perform unit tests with that user data. Hopefully this gives you some ideas of how you might be able to automate your own client-side GUI experiences. Writing this blog raised an interesting question for me. If a software product's QA lifecycle involves end-to-end system and user-acceptance testing, could an approach like this the use of QUnit or any other client-automation/scripting tool reduce testing and acceptance times? 

Post comment