This is part two of my series on Using SpecsFor.Mvc to write awesome automated acceptance tests for your ASP.NET MVC application. In this post, we’ll look at navigating around your app from SpecsFor.Mvc and at how to locate, populate, and submit forms.

SpecsFor.Mvc utilizes Selenium WebDriver under the hood, and you have full access to all the capabilities of WebDriver in your tests. That means you can navigate to any URL using Selenium’s INavigation.GoToUrl method, like so:

The problem with this approach is that it’s built on magic strings. If we were to rename our controller or action method, or if we were to change our routing, this URL may no longer be valid, and our test would fail for the wrong reason.

SpecsFor.Mvc provides a better way to perform navigation by using a strongly-typed API:

Since NavigateTo uses strongly-typed lambda expressions, it is both refactor-friendly and unaffected by changes in routing. The method fully supports navigation to action methods that accept parameters as well:

Again, this approach is loosely-typed and very likely to introduce maintenance problems both in your views as well as in your tests. Tests should enable you to change your application with confidence, not introduce additional hurdles. Fortunately there is a better way.

ASP.NET MVC provides a way to generate forms using strongly-typed lambda expressions over your view models:

This approach is the most prevalent in the community and is the one that SpecsFor.Mvc works with out of the box. Assuming you have already directed SpecsFor.Mvc to a page containing a form, you can populate the form using strongly-typed lambda expressions which are again refactor-friendly:

Under the hood, SpecsFor.Mvc is utilizing the same conventions as ASP.NET MVC’s lambda-based helpers to determine the IDs for form elements based on your model. Since both the view and the tests are based on the same conventions, your tests will stay in sync with any changes you make to your view.

Note: At this time the conventions are sealed in, but they will be exposed so that they can be overridden with alternate conventions in a future release.

After submitting a form, you can utilize MvcContrib.TestHelper to verify that your application redirected to the desired location:

The next version of SpecsFor.Mvc will include a configurable, convention-based method of verifying locations that’s also compatible with single-page applications.

Testing Validation

The final piece of interacting with forms via SpecsFor.Mvc is validation. You can test both server-side and client-side validation. Assuming you are using the out-of-the-box conventions, you can use the same fluent API for checking field validation as you use for filling out forms:

The next version of SpecsFor.Mvc will also allow you to override the underlying conventions for locating validation messages (conventions are going to be a major theme in SpecsFor.Mvc 2.0).

What’s Next?

Submitting data is great, but what about reading it back out? In the next post, I’ll show you how to find data on a page using SpecsFor.Mvc’s strongly-typed, refactor-friendly API. In the meantime, check out the project on Github, or install the package via NuGet!

About Matt Honeycutt...

Matt Honeycutt is a software architect specializing in ASP.NET web applications, particularly ASP.NET MVC. He has over a decade of experience in building (and testing!) web applications.
He’s an avid practitioner of Test-Driven Development, creating both the SpecsFor and SpecsFor.Mvc frameworks.

He's also an author for Pluralsight,
where he publishes courses on everything from web applications to testing!