Rob Smyth

Thursday 24 July 2008

Resharper Plugin Test Fixture

I've been writing a Resharper plugin, and although it does seem much easier than a Visual Studio add-in, writing any Visual Studio plugin/add-in is just plain awkward. The cost of testing is so much higher when the target product is the same as your development tool. So it seemed that the best thing to do first was to automate the basic Resharper plugin validation so that the manual testing cost is avoided/minimised. It also has the advantage of documenting my understanding of the Resharper plug-in API.

To manually test I must shutdown VS copy the DLL to a deployment folder, possibly update a registry key, and then start-up VS again. If things fail Resharper/VS are not happy and all may need to be shutodown, dlls deleted, VS started again, and maybe even a little configuration recovery. Nothing too bad but it is definitely a high cost manual test scenario.

The full tests are part of the 'SharpProbe' project. Code fragment is shown below.

[Test]
public void HasActionsRootElement()
{
Assert.IsNotNull(xmlDocument.SelectSingleNode("actions"));
}

[Test]
public void AllInsertElementsHaveValidGroupIDs()
{
Dictionary<string, int> validGroupIds = new Dictionary<string, int>();
validGroupIds.Add("ReSharper", 0);
validGroupIds.Add("VS#Code Window", 0);
validGroupIds.Add("VS#Solution", 0);
validGroupIds.Add("VS#Item", 0);
validGroupIds.Add("VS#Project", 0);

XmlNodeList nodes = xmlDocument.SelectNodes("actions/insert");
foreach (XmlNode node in nodes)
{
string groupID = node.Attributes["group-id"].Value;
Assert.IsTrue(validGroupIds.ContainsKey(groupID),
string.Format("XML insert element has unknown group-id '{0}'.", groupID));
}
}

[Test]
public void AllInsertElementsOtherThanResharperElementHaveValidActionRefIDs()
{
XmlNodeList nodes = xmlDocument.SelectNodes("actions/insert[@group-id!='ReSharper']");
foreach (XmlNode node in nodes)
{
NodeHasValidActionId(node, "action-ref");
}
}

[Test]
public void HasAtLeastOneInsertElement()
{
Assert.IsTrue(xmlDocument.SelectNodes("actions/insert").Count > 0);
}

[Test] public void HasResharperInsertElementsTahtHasValidActionIDsAndMenuText()
{
XmlNodeList nodes = xmlDocument.SelectNodes("actions/insert[@group-id='ReSharper']");
Assert.AreEqual(1, nodes.Count);
NodeHasValidActionId(nodes[0], "action");

XmlNode actionNode = nodes[0].SelectSingleNode("action");
string text = actionNode.Attributes["text"].Value;
Assert.IsTrue(text.Length > 0);
}

2 comments:

Steve Dunn said...

Hi, you don't need to copy your R# plugin binaries - there's a command line switch for devenv.exe that tell R# to load your plug-in from your development directory. In the project configuration, set Debug to 'start external program' and set it to the path to devenv.exe. In the command line arguments, type '/ReSharper.Plugin "c:/path/to/your/plugin.dll"
Hope this helps!
Cheers,
Steve (http://blog.dunnhq.com)

Rob Smyth said...

Thanks Steve, but I've given up on Resharper plugins. Seems that JetBrains do not support the plugins. Just insufficent info on how to use them.

Unless you have a source?

Rob Smyth