Monday, October 5, 2009

Visual Studio First Unit Test

Well, I decided to go with the built in unit test that Visual Studio 2008 provides simply because of the integration and everyone has it available without any installs.  The whole point is to just working with unit tests.  The lessons learned can be applied to any unit test software like NUnit.  So I started out with a simple method that does the same thing Math.Pow() does, raises a decimal to a power, returning a decimal.  (MyMath.cs)
public static class MyMath
  public static decimal MyPower(decimal num, int power)
    int i = 0;
    decimal retval = 1;

    while (i < power)
      retval *= num;

    return retval;
After creating the method, i select the Test menu in Visual Studio and New Test....  In the Add New Test dialog box, I select the Unit Test template and name it TestPower.cs, and select "Create a new Visual C# test project...".  I click OK and name the new project TestProjectSimpleUnitTest and click Create.

I am presented with a new project TestProjectSimpleUnitTest that contains TestPower.cs.  Scrolling to the end of that file, I see:
public void TestMethod1()
      // TODO: Add test logic    here
I rename that method to TestMyPower() and delete the comments.  I right click the TestProjectSimpleUnitTest project and set it as the Startup Project.  I then press F5 to start the unit test and see that it passed.

Now, lets actually test MyPower.  First thing we have to do is add a reference to the SimpleUnitTest project in the TestProjectSimpleUnitTest project.  Add a using clause at the top of the TestPower.cs file:
using SimpleUnitTest;
and fill in my test method like this:
public void TestMethodMyPower()
  Assert.AreEqual(9m, MyMath.MyPower(3, 2), "3 to power of 2");
  Assert.AreEqual(1m, MyMath.MyPower(3, 0), "3 to power of 0");
  Assert.AreEqual(27m, MyMath.MyPower(3, 3), "3 to power of 3");
All my tests pass in this case.  But, supposing they didn't it's easy to set a breakpoint in the MyPower code or in the unit test code and select debug in the Test Results pane and debug your code in a controlled fashion that does not impact your project using MyPower!

Next time I'm going to get into the real good stuff... creating unit test for a database driven application!

Thursday, October 1, 2009

Discovering the importance of Unit Tests

I used to never create unit tests for the code I'd write.  Why?  Deadlines.  Get it done, test it, send it to QA, have defects reported, rinse and repeat.  I became tired of that so I pressed my boss to give me a little more time in development so that I can create formal unit tests for my code and send stronger code to QA.  It took a littler longer to do than I'd hoped, so that I wasn't too thrilled about.  However, the results were astounding!  All programmers out there, you have to start creating unit tests for your code!  NOW!

The application I'm working on takes data in from multiple databases, processes it and writes data back out to the databases.  I had to overcome database dependency for my unit tests.  Nothing worse than getting a new database instance for development and discover 60 unit tests break.

Second obstacle probably the biggest benefit for development and that was what happens when QA finds a defect?  You need to recreate the defect.  How long does that take?  Minimum a half hour?  Sometimes days?  To recreate the defect, you need the data they were using.  Sure, you can setup your database the way QA says it was, but was it really setup exactly the way they say?  Come on, we all have that doubt in the back of our heads because it's bitten us before.  What can you possibly do to alleviate this headache?  Aren't your unit tests database independent?  So, capture the data and make a unit test out of it!

I've had a few occasions when I had a defect that had a simple one liner solution.  Out of 230+ unit tests, the fix broke about 40 or more unit test!  Would QA catch it?  During regression testing, sure!  If there were moving on like usual, no, they would have not caught those scenarios.

I'll post my experiences with unit testing and integration into Visual Studio 2008 using Resharper soon.

Here is how to create a simple Database Application Unit Test [].