testing

All posts tagged testing

odns_regexToday I had to write some utility classes to parse query parameters from one search provider and transform them to work with another search provider.  Naturally this meant a lot of work with regular expressions.

Many developers dread working with regular expressions. The syntax is arcane, the patterns can be absurdly long, and debugging them is a chore. A single character change in a regex pattern, to address one edge case, can cause failures in many other inputs. Unit test covering an array of inputs is essential to have confidence in your regex code and faith that your changes after the fact don’t break existing use cases.

But how can we accelerate the initial implementation? There are an array of tools out there to help with developing regexes, but if you don’t need any of that if you have NCrunch installed to Visual Studio.

Chances are if you are a .NET developer and practice TDD, you’ve heard of NCrunch. If you’re not familiar with it, NCrunch is a tool that (among other things) runs your unit tests for you in the background, as you type. This gives you real-time feedback on your tests which is a significant accelerator, saving you the trouble of writing a test, writing some code to make the test pass, rebuilding, running the test, repeat until green. You know right away if your code is working as intended. If it isn’t, you know immediately what you broke when you see the red lights next to your test methods. Overall it’s a great tool and I highly recommend it.

Consider this example, testing an email validation pattern:

public class Email_Regex
{
	private const string EmailPattern = @".+";
	public bool IsValidEmail(string email)
	{
		return Regex.IsMatch(email, EmailPattern);
	}
}


[TestFixture]
public class Email_Regex_Tests
{
	private Email_Regex _regex;

	[SetUp]
	private void SetUp()
	{
		_regex = new Email_Regex();
	}

	[Test]
	public void IsValidEmail_SimpleEmail_IsValid()
	{
		string testEmail = "chris.sulham@gmail.com";
		Assert.IsTrue(_regex.IsValidEmail(testEmail));
	}
}

This test will pass, but clearly the pattern isn’t going to cut it in the real world. We can add another test with an invalid email, that should make the pattern not match.

[Test]
public void IsValidEmail_NonEmailInput_IsNotValid()
{
	string testEmail = "I'm not telling you my email address!";
	Assert.IsFalse(_regex.IsValidEmail(testEmail));
}

Here we can set up an array of tests against representative inputs that we’ll run through our regex. Using NCrunch, we can make edits to the pattern and see in real time whether or not our inputs are matching. As you add more tests and have to tweak the pattern, you’ll once again know immediately which test inputs are working with your changes. Seeing the lights go red the moment you add or change a character in the pattern will remove many, many painful cycles of change, build, run tests, wonder what broke everything, change again…

Developing regular expressions this way almost makes the whole process fun.  Almost.

Download NCrunch here