Rob Smyth

Sunday 2 March 2008

VS Production/Test Macro Jumper

When using TDD it seems that repetitive patterns that we perform are:
  • Create a test fixture for a class
  • Create a test for a test a method
  • Switch between the test fixture and the production code.
I forget the author but I'm reminded I once read:
"while the job of software developers is to automate end user processes, it seems that developers are the last to automate their processes."
So with this in mind I have written a Visual Studio macro to do one of the above, switch between a test fixture and the related production code class. Depending how this goes at work I may extend this to create the fixture and create template test cases for method. See how it goes.

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module Jumper

Sub BetweenProductionClassTestFixture()
'Copyright 2008 Robert Smyth'
''
'Jump between product class file and its test fixture'
'This macro makes the assumes that all unit tests for'
'classes in a files are located in a file of the same'
'name as the file being tested (production code) with'
'a Tests suffix.'
''
'This is based on the common practice of one class per'
'file, the filename being the class name, and one test
'fixture per class.'
''
'It also assumes:'
'- All test fixtures for an assembly are located in a'
' child folder called Tests.'
'- All test fixtures are located in a mirror folder'
' structure within the child folder called Tests.'

Dim fileNameExtension = System.IO.Path.GetExtension(Application.ActiveDocument.FullName)
Dim activeProject As Project = GetActiveSolutionProject()
Dim projectPath = System.IO.Path.GetDirectoryName(activeProject.FullName)
Dim currentFilePath = System.IO.Path.GetDirectoryName(Application.ActiveDocument.FullName)
Dim classRelativePath = Right(currentFilePath, Len(currentFilePath) - Len(projectPath))
Dim currentClassName
Dim newFilePath = ""

currentClassName = System.IO.Path.GetFileName(Application.ActiveDocument.FullName)
currentClassName = Left(currentClassName, Len(currentClassName) - Len(fileNameExtension))

If (Right(currentClassName, 5) = "Tests") Then
newFilePath = Left(currentClassName, Len(currentClassName) - Len("Tests")) + fileNameExtension
newFilePath = Left(projectPath, Len(projectPath) - Len("Tests")) + newFilePath
Else
newFilePath = currentClassName + "Tests" + fileNameExtension
newFilePath = projectPath + "\Tests" + classRelativePath + "\" + newFilePath
End If


If newFilePath <> "" Then
Application.Documents.Open(newFilePath)

End If

End Sub

Public Function GetActiveSolutionProject() As Project
' Sets global miPrj = currently selected project and
' return the project to the caller.
Dim projs As System.Array
Dim proj As Project
Dim projects As Projects

projs = DTE.ActiveSolutionProjects
If projs.Length > 0 Then
proj = CType(projs.GetValue(0), EnvDTE.Project)
Return proj
End If
End Function

End Module

No comments: