The posts tagged with 'JavaScript' are listed below. You can get to each post by clicking the title in the list.


Doing BDD with SignalR and Jasmine

SignalR is one of the latest (and sexiest) elements in the .NET stack. Expect to hear more about SignalR if you haven’t already, because it delivers on the promise of push technology without the requirement of a fat client. If you’ve not yet read much about SignalR, clone the source code from GitHub or read Scott Hanselman’s post on SignalR for an introduction. The scope and inner-workings of SignalR are somewhat out of scope here, so I’ll just assume you’ve at least heard something about SignalR and that you’re interested in it but have a few questions. I mean, if you’re into BDD/TDD, you should definitely be wondering:

So how testable is SignalR? If the magic of it is based in some form of maintained connection, the implication of how one has to code asynchronously against it makes testing p-r-e-t-t-y difficult. Testing in JavaScript is pretty difficult to begin with, so now what?

There’s this amazing TDD/BDD micro-framework called Jasmine that lends itself extremely well to all sorts of different JavaScript problem domains. I learned about Jasmine from some colleagues in the Ruby community, then found some pretty awesome resources on Jasmine, and have been waiting for an opportunity to try it out. This seemed like a perfect opportunity, so I dove in.

The Calculator SignalR Hub

This example will offer a solution to the simple problem of providing basic numeric calculations. Obviously, the first operation most users will need is some addition functionality.

image

The implementation of this method might look a little strange if you’re new to SignalR. It’ll make sense in just a moment when you see the corresponding JavaScript code. Think about it this way; the Clients property of any Hub is dynamic object that will represent a corresponding JavaScript method on each of the clients connected to the Hub.

image

The controller action for the client has no special glue or magic in it. It’s basically a shell to adhere to the requirement of having an action for the views.

image

On the client, there will be a few script references to make sure SignalR works properly.

image

This is the part where the dynamic client thing should make sense. The JavaScript code below demonstrates how to call this dirt-simple SignalR Hub and to generate some action on the client.

image

The call earlier, within the implementation of the Hub, is basically a way of the server telling the client, would you please run this method and pass it this data? It isn’t a really sexy example when you see it execute, of course, but it drives the point home. SignalR makes push ridiculously simple.

image

Bring on the BDD!

As if SignalR isn’t nifty enough, Jasmine gives us the ability to set up specifications and unit tests to make sure things are working properly and to guide development. Now, we get to put them together to answer the problem of how to test the client. (I’m not knocking other methods, like WaTiN or other automated testing implementations, here, this is just another way of skinning the same kitty.)

We’ll need to include the basic script references and CSS file to make Jasmine light up. You can download those from the Jasmine site, or they’re included in the GitHub repository I’ve created for the purpose of my continued tinkering in SignalR.

image

Once the Jasmine files are in place, it doesn’t hurt to create a pulse-check specification to make sure the glue’s dry. The JavaScript object shell below will be a roadmap for how we’ll solve this problem.

image

Once the specifications have been written up, Jasmine’s environment is created and the tests are executed.

image

If you’ve pinned the tail on the donkey to this point, the results should be quite self-explanatory when you view the calculator page again. If you don’t see the tests, check the passed checkbox and the passing test will appear.

image

At this point, to test that the SignalR CalculatorHub is communicating with the client properly all that’s really needed is a way to call the Add method from in a unit test and to verify that the JavaScript code’s showSum method executed with a parameter of 4.

The first step in getting this working is to modify the test fixture class so it can be supplied any dependencies it might have. In this case, we plan on testing the calculator hub, so it’ll be passed into the fixture in it’s constructor. Also added is the addCallback field. At this point it’ll be set to false, but the plan is, to set this variable to the callback method that will be called when the calculation is completed by the hub.

image

Since the constructor’s changed it’d be wise to change the calling code, our jQuery ready method. This time, we’ll go ahead and create an instance of the SignalR CalculatorHub and it’ll be provided as a construction argument.

image

Next, a new specification is added to the init method. This specification is the unit test that will demonstrate the calculator’s being called properly from the client JavaScript.

image

It’d help at this point to take a peek at the Jasmine Wiki article on Spies to get an idea of how this sort of verification can be accomplished. Jasmine’s Fluent syntax makes it pretty self-explanatory (and including vsdoc files to provide Intellisense in Visual Studio brings in the Jasmine methods). Jasmine, like Moq and other mocking frameworks, offers unit tests the capability of checking to see if methods have been executed properly.

image

If your Jasmine tests are executed at this point, you’ll see some p-r-e-t-t-y interesting results. For about 5 seconds the browser will let you know something’s happening by making the current test’s background color yellow.

image

Then the test will complete execution and fail. Jasmine is assuming via those calls earlier assume they should wait for an asynchronous response and if it doesn’t arrive, the tests will fail. They fail because the callback methods are never executed, and the tests expect them to be .

image

That addCallback field that was added to the test fixture is how this can be accomplished. The client’s showSum method is the one thing that’s been omitted from the JavaScript code. That’s the method that the SignalR hub will try to call on each client whenever it needs to do so.

image

Within the test fixture resides the onAdd method. It just executes the fixture’s addCallback method and feeds it the results from the SignalR CalculatorHub call.

image

Once that’s all wired up, the test should pass!

image

If you’re obsessive about verifying, just change the expected value to be something wrong and re-run the test. Obviously, if the math fails, so should the test. Otherwise it’d be a pretty useless calculator!

image

Recap

SignalR and Jasmine work quite nicely together. If you apply a little OO elbow grease and take the time to wire things up with callbacks and to verify the execution of those callbacks, SignalR can be tested rather effectively. All it takes is to properly stage, and then verify, that the Hub’s method is called and that, when the Hub fires the client callback, that the callback is executed as your code expects it to be executed.

Thanks for taking the time to stop by. Happy Coding!


Testing ASP.NET MVC with QUnit - Part 1

One of the problems that face any web developer is their ability to properly test the GUI components of their sites. A few options exist, specifically Watin, with varying degrees of success. Now that I've been experimenting with the ASP.NET MVC framework I've modified a good deal of my GUI work in such a way that it minimizes form-posts and makes use of the AJAX goodies packed into jQuery. Since a lot of my work has moved to the client following my adoption of this approach I needed to investigate new options for testing. This morning I had the luck to stumble across QUnit, a jQuery testing plugin that makes life pretty easy. 

I won't spend a lot of time explaining how QUnit works. That job has been done already by the jQuery documentation team and in a great tutorial by Chad Myers . I'd encourage you take a look at those links to get a little more familiar with how QUnit works. It's quite simple and elegant, like most other plugins in the jQuery world. What I'll be demonstrating below is how you can use QUnit to unit-test ASP.NET MVC client functionality.

The first example will offer up a much-needed scenario - testing the output of controller methods that return JSON data in the form of JsonResult class instances. The TestJsonMessage() method below exemplifies a typical AJAX request. The client uses jQuery to make the call, the JsonResult is built within the Action method and returned to the client, where it can be accessed in an object-oriented manner via jQuery. 

public JsonResult TestJsonMessage()
{
  return new JsonResult
  {
    Data = new
    {
      Status = true
    }
  };
}

In the View's HTML code JavaScript will be added to perform the test. The TestJsonMessage view is loaded via jQuery's getJSON method. When the data is returned to the client it is used in the actual test code. 

$(document).ready(function()
{
  $.getJSON('/Home/TestJsonMessage', function(data)
  {
    test('TestJsonMessage status should be true', function()
    {
      equals(Boolean(data.Status), true, 'The server should return a status of true');
    });
  });
});

Once the test runs, the output below is generated, indicating the test's success. 

This example demonstrates how one might use QUnit to test their MVC actions, specifically those actions that return JSON data to the client. In part 2 of this series I'll provide an example of using QUnit to test changes that might be made to an HTML GUI as a result of MVC actions being called. 


Testing ASP.NET MVC with QUnit - Part 2

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:

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.


FindPerson Parameter

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?