An Introduction to xUnit.net for ASP.NET MVC Developers

The purpose of this blog entry is to provide you with an introduction to the xUnit.net unit testing framework, the newest unit testing framework for the .NET framework. I want to demonstrate how you can use the xUnit.net framework when practicing test-driven development. In particular, I focus on using xUnit.net when building an ASP.NET MVC application.

This blog entry is divided into three parts. In the first part, I explain how to download and reference the xUnit.net framework when building an ASP.NET MVC application. Next, I provide you with an overview of how you can create unit tests with xUnit.net. Finally, I demonstrate how to use xUnit.net when developing a very simple database-driven ASP.NET MVC application. I show you how to use test-driven development when building a simple Customer Feedback application.

Installing xUnit.net

At the time that I write this, the most recent version of xUnit.net is version 1.0.2. You can download xUnit.net from the following URL at the Microsoft CodePlex website:

http://www.Codeplex.com/xUnit

(It is not surprising that xUnit.net is posted at Microsoft CodePlex. The xUnit framework was developed by two members of the Microsoft CodePlex team: Jim Newkirk and Brad Wilson.)

After downloading the xUnit.net archive, make sure that you Unblock the archive by right-clicking the file, selecting Properties, and clicking the button labeled Unblock (see Figure 1). If you neglect to Unblock the file, then you will encounter security errors when attempting to use xUnit in your unit tests.

Figure 1 – Unblock xUnit.net

clip_image002

After you unzip xUnit.net, you should run the xUnit Installer. The installer is appropriately named xUnit.installer.exe. You can use the Installer to perform three different installation operations (see Figure 2).

Figure 2 – Using the xUnit.net Installer

clip_image004

If you use TestDriven.net or JetBrains Resharper 4.0, then you can integrate xUnit.net with these applications. Both TestDriven.net and Resharper include test runners for running unit tests. You are not required to have either TestDriven.net or Resharper installed to use xUnit.net. In this blog entry, I will not assume that you have either of these very useful applications installed on your computer.

You also are provided with the option of installing xUnit.net so that it integrates with the ASP.NET MVC new project wizard. Currently, this option is supported only for ASP.NET MVC applications written in C#. In this blog entry, I will assume that you have selected this installation option.

After you enable ASP.NET MVC integration, you can select xUnit.net as your unit testing framework whenever you create a new C# ASP.NET MVC Application. Just select xUnit.net from the Test framework drop down list (see Figure 3).

Figure 3 – Selecting xUnit.net as Your Testing Framework

clip_image006

Creating xUnit.net Tests

When you create an ASP.NET MVC application, and select the option to create a unit test project, your Visual Studio Solution contains two projects. One project contains the application that you are building and one project contains the unit tests for that application (see Figure 4).

Figure 4 – Solution with ASP.NET MVC and xUnit Projects

clip_image008

When you create a new ASP.NET MVC Web Application project, you get a sample controller named HomeController. When you create a new xUnit.net unit test project, you get a sample unit test for the HomeController named HomeControllerFacts. I’ve included part of this sample unit test in Listing 1.

Listing 1 – HomeControllerFacts.cs

using System.Web.Mvc;
using Xunit;
using TestSite.Controllers;
 
namespace TestSiteTests.Controllers
{
    public class HomeControllerFacts
    {
        public class Index
        {
            [Fact]
            public void ReturnsViewResultWithDefaultViewName()
            {
                // Arrange
                var controller = new HomeController();
 
                // Act
                var result = controller.Index();
 
                // Assert
                var viewResult = Assert.IsType<ViewResult>(result);
                Assert.Null(viewResult.ViewName);
            }
 
        }
    }
}

The code in Listing 1 tests the Index() method of the HomeController class. Notice that Listing 1 contains a normal C# class named HomeControllerFacts. When using xUnit.net, unlike other unit testing frameworks, you do not need to decorate your classes with a special attribute.

Notice that the HomeControllerFacts class includes a nested Index class. The nested Index class contains all of the test methods related to testing the Index() method of the HomeController class. You don’t need to nest classes in this manner if you don’t want to. However, this pattern does neatly group all tests associated with a particular method under test.

The Index class contains a single test method named ReturnsViewResultWithDefaultViewName(). This method is decorated with a [Fact] attribute. You must mark each of your test methods with this attribute.

The test method checks whether the Index() action returns a view that does not contain a name. Following the William Wake pattern, the test consists of three parts: Arrange, Act, and Assert. The Arrange section is used to setup the objects required for the test: the HomeController. The Act section calls the Index() method. Finally, the Assert section verifies that the name of the view returned by the Index() method has the value Null.

Facts Not Tests

You might have noticed that xUnit.net, unlike other unit testing frameworks, uses the term Fact instead of Test. For example, you decorate test methods with a [Fact] attribute. The name of the test class is HomeControllerFacts instead of HomeControllerTests. What is going on here?

There has been no end of confusion about the purpose of test-driven development. Most people still equate test-driven development with testing. In other words, most people still believe that the primary reason to practice test-driven development is to develop a set of regression tests for your application.

The goal of test-driven development is not to build a bunch of tests (although this is a nice side effect). The goal of test-driven development is to build a well-designed application. Test-driven development forces you to think about how your code will be used before you actually write the code. For this reason, some people have recommended removing the word test from the name test test-driven development. I assume that the term Fact is used instead of Test for this reason.

The xUnit.net Assert Class

Normally, the very last line in a unit test method is an assertion that something is true or false. You perform the assertion by using the xUnit.net Assert class.

The Assert class exposes 19 methods for performing 19 different types of assertions:

· Contains – Verifies that a string contains a specified substring or a collection contains a specified item.

· DoesNotContain – Verifies that a string does not contain a specified substring or a collection does not contain a specified item.

· DoesNotThrow – Verifies that code does not throw an exception.

· Empty – Verifies that a collection is empty.

· Equal – Verifies that two objects are equal.

· False – Verifies that a specified condition is false.

· InRange – Verifies that a value is greater than and less than two other specified values.

· IsAssignableFrom – Verifies that an object is a given type or a derived type.

· IsNotType – Verifies that an object is not the specified type.

· IsType – Verifies that an object is the specified type.

· NotEmpty – Verifies that a collection is not empty.

· NotEqual – Verifies that two objects are not equal.

· NotInRange – Verifies that a value is greater than and less than two other specified values.

· NotNull – Verifies that an object is not null.

· NotSame – Verifies that two objects are not the same instance.

· Null – Verifies that an object is null.

· Same – Verifies that two objects are the same instance.

· Throws – Verifies that an exception is thrown.

· True – Verifies that a specified condition is true.

One of the most common types of assertions is Assert.True(). You use Assert.True() to test whether a particular condition is true. For example, you might want to verify that the name of a view returned by an action has the name “Index”:

[Fact]
public void ReturnsViewResultWithViewNameIndex()
{
    // Arrange
    var controller = new HomeController();
 
    // Act
    var result = controller.Index() as ViewResult;
 
    // Assert
    Assert.True(result.ViewName == "Index");
}

The xUnit.net test framework handles exceptions in an interesting way. Most other unit test frameworks (including MS Test) use an attribute to mark whether or not a test method is expected to throw an exception. The xUnit.net test framework, in contrast, uses the Assert.Throws() method like this:

[Fact]
public void ThrowsArgumentNullException()
{
    // Arrange
    var controller = new HomeController();
 
    // Act
    Assert.ThrowsDelegate act = delegate { controller.Index(null); };
 
    // Assert
    Assert.Throws<ArgumentNullException>(act);
 
}

This method verifies that calling the Index() action with a null parameter raises an ArgumentNullException. Notice the use of the anonymous delegate. The anonymous delegate is used to represent the code that you expect to raise the exception.

If you prefer, you can use a lambda instead of an anonymous delegate like this:

[Fact]
public void ThrowsArgumentNullException()
{
    // Arrange
    var controller = new HomeController();
 
    // Act
    Assert.ThrowsDelegate act = () => controller.Index(null);
 
    // Assert
    Assert.Throws<ArgumentNullException>(act);
 
}

Personally, I find the anonymous delegate version more readable and less confusing than the lamda (empty parentheses just look weird).

Using the Test Runners

After you create your xUnit.net tests, you need to run them. The xUnit.net framework supports 4 distinct test runners:

· GUI Test Runner

· Console Test Runner

· TestDriven.NET Test Runner

· Resharper 4.0 Test Runner

I’ll show you how to use each of these Test Runners in turn.

Using the GUI Test Runner

Let’s start with the GUI Test Runner. You launch the GUI Test Runner by executing the application named xunit.gui.exe. After you open this Test Runner, you see the application in Figure 5.

Figure 5 – GUI Test Runner

clip_image010

You run tests by opening the assembly generated by your xUnit.net test project. Select the menu option File, Open and navigate to your tests assembly. For example, if your xUnit.net test project is named TestSiteTests, then the tests assembly will be located at the following path:

\TestSiteTests\bin\Debug\TestSiteTests.dll

After you open the tests assembly, you can run your tests by clicking the Run button. Figure 5 illustrates what happens when you run a test that fails.

The GUI Test Runner is extremely limited. The GUI Test Runner does not enable you to run a particular subset of tests. You must run all of the tests in an assembly or none of them.

Using the Console Test Runner

The second test runner is the Console Test Runner. You open this test runner by executing the application named xunit.console.exe from the command line.

In Windows Vista, you can open a command prompt from a particular folder by holding down the shift key while right-clicking the folder. If you hold down the shift key, you’ll see the extra context menu option Open Command Window Here. You can type the following DOS command to add the path to the xunit.console.exe to the paths that are searched when executing an application:

set path=%path%;%cd%

Next, you can navigate to the folder that contains the test assembly and execute xunit.console.exe like this:

xunit.console.exe TestSiteTests.dll

Figure 5 illustrates the output from a failed test.

Figure 5 – Console Test Runner

clip_image012

I find running tests with the Console Test Runner incredibly painful. However, having the Console Test Runner makes it possible to run your xUnit.net tests from an automated process. For example, as part of a code check-in policy, you could execute the Console Test Runner.

Using the Resharper 4.0 Test Runner

Resharper 4.0 is a commercial application that you can buy from JetBrains at:

http://www.JetBrains.com

Resharper includes a very easy to use test runner. The xUnit.net testing framework integrates with the Resharper test runner if you select this option when executing the xunit.installer.exe tool.

To use the Resharper test runner to run an xUnit.net test, you simply click on a magic button that appears next to your unit tests in your source code file. For example, in Figure 6, there are two special icons that appear in the source code editor’s left gutter. If you click the first icon, all the tests in the xUnit test class are run. If you click the second icon, only the selected unit test is run.

Figure 6 – Resharper Test Runner

clip_image014

The result of executing a unit test is displayed in the Unit Test Sessions window (see Figure 7). Use the top pane of the window to see at a glance which tests succeeded and which tests failed. The bottom pain of the window contains error information for tests that failed.

Figure 7 – The Unit Test Sessions Window

clip_image016

The Resharper Test Runner is very easy to use. It also has a very pretty test results window. The only downside to using Resharper to run your xUnit.net tests is that Resharper costs money (most people think the application is worth its weight in gold).

Using the TestDriven.NET Test Runner

The final Test Runner is the TestDriven.NET Test Runner. To use this Test Runner, you must have TestDriven.NET installed on your computer. Furthermore, you must enable TestDriven.NET integration with the xunit.installer.exe tool. You can download TestDriven.NET from the following URL:

http://TestDriven.net/download.aspx

There is both a commercial and personal use version of TestDriven.NET. The personal use version is a free download.

After you install TestDriven.NET, you can run tests by right-clicking either a test class or a particular test method in the Visual Studio Source Code Editor and selecting the menu option Run Tests (see Figure 8).

Figure 8 – Running tests with TestDriven.NET

clip_image018

(I used to think that the Run Test icon was an icon of the devil’s pitchfork. It took me a while to figure out that the icon actually is an icon of a rocket ship blasting off from earth.)

The results of a test run are displayed in the Visual Studio Output window. The Output window in Figure 9 displays the results of a failed test.

Figure 9 – TestDriven.NET Test Results

clip_image020

Walkthrough: Creating a Product Feedback Application

In this last section of this blog entry, I am going to walk-through the process of building a new ASP.NET MVC Web Application. I am going to demonstrate building the application using test-driven development with xUnit.net.

We are going to build an extremely simple application. In this section, we are going to build a Product Feedback application. The application consists of a single form that a customer can submit to provide feedback to a company on a particular product.

The application is intentionally simple. The goal is to demonstrate that test-driven development makes sense even when building a simple application.

What are the Requirements?

Let me start by listing some initial requirements for the application. These requirements might change over time in response to changing customer needs. However, we can use the following initial set of requirements as a starting point:

1. When a customer first arrives at the website, the customer sees a form with two form fields: Product Name and Product Description. The first field represents the name of the product. The second field represents the customer’s experience using the product.

2. The customer can submit the form data to a database.

Only two requirements. I told you that this was going to be a really simple application!

Start with a Failing Test

We need to start by writing a unit test. We write the unit test first before writing any code for our Product Feedback application. We expect the first test to fail.

First, we want to make sure that our application returns a particular view when the customer arrives at the website:

[Fact]
public void ReturnsIndexView()
{
    // Arrange
    var controller = new HomeController();
 
    // Act
    var result = controller.Index() as ViewResult;
 
    // Assert
    Assert.True(result.ViewName == "Index");
}

This test checks for a view named Index. If the HomeController.Index() action does not return this view, then the test fails. When you run this test, the test will fail because the HomeController.Index() action does not explicitly return the Index view.

So, our next task is to write just enough code for the test to pass. So let’s modify the HomeController.Index() action like so:

public ActionResult Index()
{
    return View("Index");
}

If we run our single unit test again, the unit test will now pass.

Next, let’s write a unit test to check whether the ProductName and ProductDescription fields are submitted. This test will fail since we have not created the Insert() method on our HomeController class yet:

[Fact]
public void SubmitProductNameAndDescription()
{
    // Arrange
    var controller = new HomeController();
 
    // Act
    var result = controller.Insert("Laptop", "Great product!");
}

Our test project won’t even build with this new test method since the Insert() method does not exist yet. This counts as a failing test. Let’s go ahead and create the Insert() action for our HomeController class:

public ActionResult Insert(string productName, string productDescription)
{
    return null;
}

Notice that I have written the minimum amount of code necessary to cause the test to the pass.

Initializing the Database with Dependency Injection

Next, we need to add the Product Name and Product Description to the database. Here is where things get a little more complicated and a little more controversial. Here’s my first test for submitting the product information to the database:

[Fact]
public void InitializeDataContext()
{
    var dataContext = new ProductFeedbackDataContext(testDBPath);
    var controller = new HomeController(dataContext);
}

This test looks simple, but it will force us to do a lot of work. This test verifies that the HomeController class will accept a LINQ to SQL data context named ProductFeedbackDataContext. Right now, of course, the HomeController class doesn’t even include a constructor. Furthermore, we don’t have a database, a database table, or a data context in our project. So, if we run this test, the test will fail for any and all of these reasons.

Here’s how we can rewrite the HomeController class to pass this test:

using System.Web.Mvc;
using ProductFeedback.Models;
 
namespace ProductFeedback.Controllers
{
    public class HomeController : Controller
    {
        private ProductFeedbackDataContext _dataContext;
 
        public HomeController():this(new ProductFeedbackDataContext())
        {}
 
        public HomeController(ProductFeedbackDataContext dataContext)
        {
            _dataContext = dataContext;
        }
 
        public ActionResult Index()
        {
            return View("Index");
        }
 
        public ActionResult Insert(string productName, string productDescription)
        {
            return null;
        }
    }
}

I’ve rewritten the HomeController to use Dependency Injection. The HomeController class now has a private field named _dataContext that represents a LINQ to SQL data context. Notice that the HomeController class now has two constructors: a parameterless constructor and a constructor that accepts a data context.

When the ASP.NET MVC framework creates a HomeController in response to a user request, the framework will create the HomeController class using the parameterless constructor. When the ProductFeedbackDataContext class is created without any parameters, the database connection string is loaded from the web configuration file. In other words, in production, the HomeController will get its database connection string from the web configuration file.

The constructor with the parameter is there so we can switch the data context when testing the HomeController. In our unit test, we pass in a test data context. This approach enables us to supply an explicit database connection string.

To get all of this to work, we need to create a new database in our application. Add a new database to your App_Data folder by right-clicking the App_Data folder and selecting Add, New Item and selecting the SQL Server Database template. Name the new database ProductFeedbackDB.

Next, add the following table to the new database. Name the new database table ProductFeedback.

Column Name Data Type Is Identity
Id int True
ProductName nvarchar(50) False
ProductDescription nvarchar(max) False

 

Next, you need to add a LINQ to SQL class to your Models folder named ProductFeedback that represents the new database. Right-click the Models folder and select the menu option Add, New Item and select the LINQ to SQL Classes template. Name the new LINQ to SQL Classes ProductFeedback. After the Object Relational Designer opens, drag the ProductFeedback table onto the designer surface (see Figure 10).

Figure 10 – The Product Feedback Data Context

clip_image022

Finally, we need to add some assembly references to our test project to get the test project to compile. You need to right-click the References folder and select the menu option Add References. Add a reference to System.Data and System.Data.Linq.

After you complete all of these steps, the InitializeDatabase() unit test will compile and pass. However, both of the previous tests that we created will now fail because the HomeController now needs a data context whenever we instantiate it from a test – otherwise we get a null reference exception. We’ll fix this issue in the next section.

Including a Database in our Tests

We are going to test whether our data gets submitted into the database. Creating a unit test that tests a database in the context of test-driven development is controversial. For example, Michael Feathers who is the author of the excellent book Working Effectively with Legacy Code, writes that you should never test a database directly (see page 14). His reasoning is straightforward. Executing a unit test against a database takes too long. Since you should be executing your unit tests continuously, whenever you make a change to your application, slow running unit tests will undermine the process of test-driven development.

However, we are in the very early stages of building an application. We don’t need to execute hundreds of tests. Instead we just need to execute a few tests. If our database tests start to slow us down, we always have the option of separating our database tests into a separate group of tests. We can then execute the slower set of tests every once in a while (a couple of times a day) instead of with every code change. For right now, executing our tests against the database will give us confidence that we are making progress building our application.

The new version of our test class, HomeControllerFacts.cs, is contained in Listing 2.

Listing 2 – HomeControllerFacts.cs

using System;
using System.Web.Mvc;
using ProductFeedback.Models;
using Xunit;
using ProductFeedback.Controllers;
using System.Linq;
using System.Data.Linq;
 
namespace ProductFeedbackTests.Controllers
{
    public class HomeControllerFacts
    {
        private const string _connectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\ProductFeedback\ProductFeedback\App_Data\ProductFeedbackDB.mdf;Integrated Security=True;User Instance=True";
        private readonly ProductFeedbackDataContext _dataContext;
 
        public HomeControllerFacts()
        {
            _dataContext = new ProductFeedbackDataContext(_connectionString);
            _dataContext.ExecuteCommand("truncate table ProductFeedback");
        }
 
        [Fact]
        public void IndexReturnsIndexView()
        {
            // Arrange
            var controller = new HomeController(_dataContext);
 
            // Act
            var result = controller.Index() as ViewResult;
 
            // Assert
            Assert.True(result.ViewName == "Index");
        }
 
        [Fact]
        public void InsertSubmitProductNameAndDescription()
        {
            // Arrange
            var controller = new HomeController(_dataContext);
 
            // Act
            var result = controller.Insert("Laptop", "Great product!");
        }
 
        [Fact]
        public void InsertInitializeDataContext()
        {
            var controller = new HomeController(_dataContext);
        }
 
    }
}

Notice that the new version of the HomeControllerFacts class includes a constructor that creates a data context. Each of the test methods has been rewritten to take advantage of the data context created by the constructor.

One other thing that you should notice about the constructor. It includes a SQL call that removes all of the records from the ProductFeedback database table. The ProductFeedback database table is truncated. The idea is to start with a fresh database table when each test is executed.

It is important to emphasize that the code in the constructor executes again for each test. So, in the case of the HomeControllerFacts class, the call to truncate the database happens three times. This is good. This means that each test remains atomic. One test method does not affect the outcome of another test method.

Testing If Database Data is Submitted

Now that we have rewritten our test class, we can verify that the HomeController.Insert() action actually submits data to the database. Here is a new test named InsertAddData() that succeeds just in case a new record actually gets inserted into the database:

[Fact]
public void InsertAddData()
{
    // Arrange
    var controller = new HomeController(_dataContext);
    string productName = "Laptop";
    string productDescription = "Great Product!";
    // Act
    var result = controller.Insert(productName, productDescription);
 
    // Assert
    var feedback = _dataContext.ProductFeedbacks.First();
    Assert.True(feedback.ProductName == productName && feedback.ProductDescription == productDescription);
} 

If we run this test, the test will fail. We haven’t added any logic to our HomeController.Insert() action to add anything to the database. Let’s do that now:

public ActionResult Insert(string productName, string productDescription)
{
    var feedback = new Models.ProductFeedback();
    feedback.ProductName = productName;
    feedback.ProductDescription = productDescription;
    _dataContext.ProductFeedbacks.InsertOnSubmit(feedback);
    _dataContext.SubmitChanges();
    return null;
}

The Insert() action now includes LINQ to SQL code that will insert the product name and product description into the database. If we run our tests, all of the tests will pass.

Next Steps in Our Application

I am going to stop working on the Product Feedback application here. But I did want to emphasize that there are several additional tests that we should write for our simple application. For example, right now, we are not performing any validation on the parameters being passed to the HomeController.Insert() method. We are not checking the values of the product name or product description parameters for illegal values. In the case of a production application, we would need to verify that values such as empty strings are not inserted into the database.

The other thing to notice about our progress to this point is that we never actually visited the website that we were building. In fact, we never actually created the views for the website. At a certain point, just to keep your sanity, you will want to make sure that you have a real application behind the tests.

Summary

The purpose of this blog entry was to provide you with an introduction to the xUnit.net testing framework and demonstrate how you can use xUnit.net in the context of test-driven development when building an ASP.NET MVC application.

In the first section, I explained how you can download and setup xUnit.net. Next, I explained the basics of creating xUnit.net tests. You learned about the different types of assertions that you can make with the Assert class. I also demonstrated each of the four Test Runners included with xUnit.net: the GUI Test Runner, the Console Test Runner, the Resharper Test Runner, and the TestDriven.NET Test Runner.

In the final section of this blog entry, I walked through building an ASP.NET MVC application using the xUnit.net framework. We created a very simple Product Feedback application that enables a customer to submit feedback to a database. The design of the application was driven by the need to satisfy each of the xUnit.net tests that we created.

10 Comments

  • @Troy - Thanks for the reference to Gallio. I have heard of it, but it sounds like I definitely need to look into it.

  • " ... some people have recommended removing the word test from the name test test-driven development."

    seems to be one "test" too many: test test-driven development.

    Thus: removing the superfluous "test" leaves "test-driven development" in
    " ... some people have recommended removing the word test from the name test-driven development."

    So removing "test" gives simply "... -driven development."

    Since '-' can mean not, removing "test" gives "not driven development" which likely leads to poorly crafted code that lacks robustness. Ergo, it's likely not a good idea to take the 'T' out of 'TDD'.

    regards, gerry
    gerry.lowry@abilitybusinesscomputerservices.com

  • This has to do with the var vs. actual type debate. I think e.g. the delegate assertion could be made more readable by changing to:
    var act = () => controller.Index(null);

    (Apologize if I miss something I'm on a cafe without VS2008 to validate)

  • Sorry, but I still don't understand what is the purpose of unit testing? while I understand it from a technical view, I think I still didn't get the theory behinde using unit testing and if it worth the time it eats from development time, more focus on the theory of unit testing for asp.net MVC would be apperciated.

  • I tried to install xunit 1.0.3 on windows vista ultimate with webExpress & Visual C# Express 2008 and aspnet.mvc beta installed and the install failed since aspnet.mvc was not installed? The install did not recognize aspnet.mvc beta, any workarounds

  • "The Assert class exposes 19 methods for performing 19 different types of assertions" ~~ xUnit is now at version 1.0.3.

    The help file xunit-1.0.3.chm from http://www.codeplex.com/xunit/Release/ProjectReleases.aspxis useful here.

    Also useful is Visual Studio Intellisense. Type:
    Assert.
    followed by
    Ctrl+Space

  • In his comment Richard [Friday, November 14, 2008 10:29 PM]
    mentions problems with "with webExpress & Visual C# Express 2008". I assume Richard means Visual Web Developer 2008 Express edition.

    There are two layers to this problem:

    (a) VWD 2008 Express does NOT work with ASP.NET MVC.
    VWD 2008 Express SP1 or later is required.

    (b) Various unit testing frameworks do not appear
    to integrate easily with VWD 2008 SP1.
    imo, this is a shortcoming because ASP.NET MVC
    has among its selling points*: Testability - support for Test-Driven Development.

    Charlie Poole, regarding NUnit, wrote in part:
    "Without a template, you can still write tests for MVC, you just have to type all the code in."
    This could probably be said for xUnit too.
    The problem is VWD 2008 SP1 users are more likely to be
    novices than they are likely to be seasoned TDD developers.

    * Catch-22: ASP.NET MVC is to be an enabler of TDD paradigms. VWD 2008 SP1 enables ASP.NET MVC.
    http://www.asp.net/mvc/
    Sadly, VWD 2008 SP1 does not seem to easily integrate with TDD frameworks and tools.

  • The xUnit.net Assert Class ... the descriptions for the two methods InRange and NotInRange are identical:
    InRange – Verifies that a value is greater than and less than two other specified values.
    NotInRange – Verifies that a value is greater than and less than two other specified values.

    From the help file xunit-1.0.3.chm [http://www.codeplex.com/xunit/Release/ProjectReleases.aspx]:
    InRange: Verifies that a value is within a given range.
    NotInRange: Verifies that a value is not within a given range, using the default comparer.

    Note: Both InRange and NotInRange have a second form that allows specification of a comparer:
    Type: System.Collections.Generic.IComparer(T)

  • set path=%path%;%cd% is UNCLEAR from "Using the Console Test Runner", above.

    The environment variable "cd" is NOT defined by default.

    Assume for example that you've unzipped the xUnit distribution (currently xunit-1.0.3.zip) to c:\xunit103.

    A better way to write "set path=%path%;%cd%" is:

    set xUnitConsoleRunnerPath=c:\xunit103
    set path=%path%;%xUnitConsoleRunnerPath%

    Or, in one line as simply:
    set path=%path%;c:\xunit103

    This change to your path is temporary. Open another command prompt, type
    set path
    to see the path and you'll notice the path to
    xunit.console.exe is missing.

    If your system path environment variable is not too long, you can also permanently add the path to xunit.console.exe to your system path environment variable. {Right click "My Computer", select Properties, Advanced, Environment Variables}

    Reference: http://support.microsoft.com/kb/830473
    "Command prompt (Cmd. exe) command-line string limitation"

  • An introduction to the xunit net testing framework.. Awful :)

Comments have been disabled for this content.