I’ve been working in Visual Studio a lot lately, and I’ve found a few handy plugins that are very helpful for effective test writing. A good way to show these off is to follow my process for creating a new class and test via Test Driven Development. My goal here is to improve speed by removing the need for using the mouse (not to mention reduce the risk of repetitive strain injuries).
Here’s the short version:
|Navigate to a file in the test project||NavigateToTest||Ctrl+G|
|Jump to Solution Explorer||Resharper||Atl+Shift+L|
|Create new test file||Visual Studio||Ctrl+Shift+A|
|Move class under test to matching folder in core project||Resharper||Ctrl+R, Ctrl+O|
|Vertical split between test and class||VsVim||:vsp|
|Move files between split tabs||Visual Studio||Ctrl+W, Ctrl+H/L|
|Jump between files while editing||TabGroupJumper||Ctrl+W, H/L|
|Run the test||Resharper||Ctrl+U, Ctrl+R|
Now let’s take a look at the details.
1. Create the Test
Let’s say you have the following structure:
Project: MyProj Namespace: Foo Class: MyBar.cs Project: MyProj.Test Namespace: Foo Class: MyBarTest.cs
You currently have
MyBar.cs open, and you want to create new class
MyBaz.cs and test
MyBazTest.cs. But you’re using TDD, so you want to create
MyBazTest.cs first. How do you create the file without using the mouse? You need to get over to Solution Explorer, specifically in the project
MyProj.Test. That’s where some of the handy plugins I’ve found come in.
I do this in a quick two-step process. The first step is to jump to a file in the test project. So you want to go from
MyBarTest.cs. Thankfully, plugin NavigateToTest lets you jump from a class to its test, and vice versa. It is based solely on filename convention —
Xyz.cs goes to
XyzTest.cs, regardless of what classes are defined in either file. This is perhaps less robust than an annotation system, but it’s really simple to understand, and it handles every case for which I’ve needed it. I have it bound to Ctrl+G.
Next step, how do you get right to
MyProj.Test in Solution Explorer from
MyBarTest.cs? Resharper has the answer — a command named
Resharper_LocateInSolutionExplorer. I have it bound to Alt+Shift+L.
Now that you are in the right project, the standard Visual Studio binding
Project.AddNewItem (Ctrl+Shift+A) will bring up the New File dialog. I also created an NUnit template to fill in the basics of a unit test. You can see it at this gist.
2. Write the Test
So now you are in
MyBazTest.cs, and you’re ready to get going. The next step is to use Hate-Driven Development to flesh out the class as we write the test. Within that rubric, I have found a particular method that works well for me. I start typing what would be:
private MyBaz _subject;
MyBaz will want to auto-complete to
MyBazTest. I let it, then delete the Test part. This is a real help in making sure you type the correct words for longer class names. At that point, I create the class
MyBaz in the same file, then move it. If you create it in a new file, it will create that file in project
MyProj.Test, which isn’t what you want. NavigateToTest will get you to the new file, but it is still an extra step.
3. Create the Class
Instead I create the class in the same file, then move it to the correct project folder (Resharper_Move, bound to Ctrl+R, Ctrl+O for me). Basically that just means removing the
.Test from the project name (
Now if I want to create an interface for my new class, or any new interfaces it uses as dependencies, they can stay in
MyBaz.cs. If I want to move a new dependency interface later, instead of using
Alt+Enter to move it to
IMyDependencyClass.cs, I use move to another file (Resharper_Move again) and just delete the
I from the suggested
IMyDependencyClass.cs, thus putting it into
IMyDependencyClass‘s eventual implementation
MyDependencyClass will ultimately reside).
Additional Helpful Commands
You might well want to look at your class at the same time as your test. Thankfully, using VsVim, you can use the
:vsp command and get split panes.
But wait a minute — what if your test is on the right and your class is on the left, and you want them to switch places? Thankfully, Visual Studio has a built in
Window.MoveToNextTabGroup command that will do just the trick. I have it bound to Ctrl+W, Ctrl+L. I have
Window.MoveToPreviousTabGroup bound to Ctrl+W, Ctrl+H.
One more thing, how do you move back and forth between windows? NavigateToTest will work, of course, but one other plugin I have found invaluable is TabGroupJumper. It lets you bind a key combination to jump direction-ally between tab groups (left, right, up, down). I use the standard Vim bindings for this (e.g. Ctrl+W, L to go to the right tab).
Feels like there’s one more thing. Oh yeah, running the test! From anywhere within the test method,
Resharper_UnitTest_RunContext (Ctrl+U, Ctrl+R) will run the test. It will also run all tests in the current Test class if you are outside the scope of a particular test method.
There — an entire test and class without using the mouse. With apologies to Douglas Engelbart, I think removing the mouse from this process is pure win.