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:
Step | Plugin | Key press |
---|---|---|
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 MyBar.cs
to 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;
Typing 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 (MyProj.Test/Foo
=> MyProj/Foo
).
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 MyDependencyClass.cs
(where 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.
Conclusion
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.