Wednesday, June 6, 2012

Save a little time when writing unit test using VS.NET Macro


- As a unit testing passioner, I write a lot of unit tests for my code. But repeating adding test attributes to classes and methods, adding resharper ignore InconsistentNaming statement or adding AAA pattern are killing me. So I thought of making some awesome macros to save my time.
- Basically, when I add a test class, the file will originaly be like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyProject
{
    class NewTestClass
    {
    }
}

- And I want it to be like this after a few key presses:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

// ReSharper disable InconsistentNaming
namespace MyProject
{
    [TestClass]
    public class NewTestClass
    {
        [TestMethod]
        public void Should_be_implemented_NOW()
        {
            // Arrange


            // Action


            // Assert

        }
    }
}
// ReSharper restore InconsistentNaming

- This is archivable with following macros:
Sub CreateTestClassAttribute()
 DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
    DTE.ActiveDocument.Selection.Text = "public "
    DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
    DTE.ActiveDocument.Selection.NewLine()
    DTE.ActiveDocument.Selection.LineUp()
    DTE.ActiveDocument.Selection.Text = "[TestClass]"
    DTE.ActiveDocument.Selection.EndOfLine()
    DTE.ActiveDocument.Selection.LineUp(False, 3)
    DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, True)
    DTE.ActiveDocument.Selection.Text = "using Microsoft.VisualStudio.TestTools.UnitTesting;"
    DTE.ActiveDocument.Selection.EndOfLine()
    DTE.ActiveDocument.Selection.NewLine()

    DTE.ActiveDocument.Selection.NewLine()
    DTE.ActiveDocument.Selection.Text = "// ReSharper disable InconsistentNaming"
    DTE.ActiveDocument.Selection.EndOfLine()
    DTE.ActiveDocument.Selection.LineDown(False, 8)
    DTE.ActiveDocument.Selection.EndOfLine()
    DTE.ActiveDocument.Selection.Text = "// ReSharper restore InconsistentNaming"
    DTE.ActiveDocument.Selection.LineUp(False, 3)

    CreateTestMethod()
End Sub
Public Sub CreateTestMethod()
    DTE.ActiveDocument.Selection.NewLine()
    DTE.ActiveDocument.Selection.Text = "[TestMethod]"
    DTE.ActiveDocument.Selection.NewLine()
    DTE.ActiveDocument.Selection.Text = "public void Should_be_implemented_now()"
    DTE.ActiveDocument.Selection.NewLine()
    DTE.ActiveDocument.Selection.Text = "{"
    DTE.ActiveDocument.Selection.NewLine()

    DTE.ActiveDocument.Selection.Text = "// Arrange"
    DTE.ActiveDocument.Selection.NewLine(3)

    DTE.ActiveDocument.Selection.Text = "// Action"
    DTE.ActiveDocument.Selection.NewLine(3)

    DTE.ActiveDocument.Selection.Text = "// Assert"
    DTE.ActiveDocument.Selection.NewLine()
    DTE.ActiveDocument.Selection.LineUp(False, 6)
End Sub

- Well, the steps are simple:
  1. In your VS.NET click Tool -> Macros -> Macro Explorer and paste these macros to the RecordingModule.
  2. Choose Tool again -> Options -> Keyboard. Type in Macros, choose these 2 macros and bind your favorite hot key for it like picture below:


- I choose Ctrl F - Ctrl C to make a test class with first test method and Ctrl F - Ctrl M to add another Test method.
- Hehe, It's DRY principle in unit testing. I has been using different Unit testing frameworks like NUnit, MBUnit, etc but in this post, I used VS.NET test framework. You properly need to alter the macros a little bit to fit your needs. Now enjoy your tests. Cheers



3 comments:

hoanang_118 said...

Thanks You! Can You help me code to find .NET IDE location for VS 2008? I hope to receive your feedback. Thanks You very much

Bình Trọng Án said...

Your video only can run in Chrome browser. You can upload Youtube or vimeo, and you easily share with everybody

Van Nguyen said...

@Binh Thanks.
@hoanang_118: Sorry, I'm not quite sure what you meant by "code to find .NET location". Is it relevant to this post?

Post a Comment