The Five Minute Guide to FxCopUnit
By Roy Osherove
Blog: www.Iserializable.com
Email: Roy@Osherove.com
Writing Integration Tests with FxCopUnit:
5. Create a new test fixture class
6. Inherit your class from FxCopTestFixture
Add the attribute to the top of the class to specify the location of your custom
rules: [FxCopCustomRuleLocation("TeamAgile.FxCopRuleTesting.SampleRules.dll")]
7. Create a new test:
[Test]
[FxCopRuleToTest("Rule0001", "FxCopCustomRules.CustomRules",true)]
public void RunRuleAgainstMethod()
{
}
Note the FxCopRuleToTest attribute on the test. Specify the rule ID and Rule category as written in the Rule XML file manifest located inside your custom rules library (in the sample source it is RuleManifest.Xml – complied as Embedded resource).
The third parameter setup up FxCop engine so that the current test library will also be the main target to test the rules against.
Alternatively, you can specify the name of the target assembly to test against.
You can also specify the specific type that your rule will run against (all other types in the assembly will be ignored by the rules engine) .
Here’s a test that specifies a rule, and a specific method to test against.
It then tells FxCop to analyze the targets and does some simple asserts against the resulting FxCop report.
[Test]
[FxCopRuleToTest("Rule0001", "FxCopCustomRules.CustomRules",true)]
public void RunRuleAgainstMethod()
{
MethodInfo
methodInfo = MethodBase.GetCurrentMethod() as MethodInfo;
FxRunner.EnableMethodToCheck(methodInfo);
FxRunner.Analyze();
FxReport.Assert.AtLeastOneAnalysisProblem();
Console.WriteLine(FxReport.Document.InnerXml);
}
The test uses two objects which are available once you inhering from FxCopTestFixture:
FxRunner:
Helper used to specify rules, types and other logic, as well as to start the analysis process by FxCop.
FxReport:
A report object that is generated only after calling FxRunner.Analyze(). It will be null before that.
Asserting against output:
Most of the asserts should be performed against the FxReport object, which already has a property named “Assert”. It is an AssertFxCop object which has some very simple asserts in it. It can be extended though- it’s a partial class. (so is the FxCopReport class).
It’s possible to create elegant small tests which require little to no configuration whatsoever that test out your custom rule’s ability to verify problems.
It’s so simple in fact, that there’s no need to use FxCopUnit , unless you absolutely want to test your rule as part of a fully integrated rules framework.
To achieve simple FxCop unit tests, take a look at FxCopUnitTests.cs file in teamAgile.FxCopRuleTesting.csproj.
Here’s a sample unit test:
[Test]
public void InvokeMyRuleWithMethodInfo()
{
MethodInfo
someMethodInfo = MethodBase.GetCurrentMethod()
as MethodInfo;
Microsoft.Cci.Method
methodData = Microsoft.Cci.Method.GetMethod(someMethodInfo);
MyRule
ruleUnderTest = new MyRule();
ProblemCollection
problems = ruleUnderTest.Check(methodData);
Assert.Greater(0,problems.Count);
}
A custom rule can accept many
kinds of inputs, but ultimately the most important ones are “Member” and “TypeNode”.
Here’s the hiearchy for
Member these:
It’s pretty simple: For each type. There’s a static method on the counter type to get that transformation. In the test above to get a Method object, I used the static Method.GetMethod(MethodInfo) to get what I need.
You’ll find the same thing for Event, TypeNode and many others.All that’s left is to create a new instance o fyour custom rule (without needing FxCop engine at all), and invoking it’s check method with the data you have specified.
All that’s left is to check stuff on the problem collection that you need to get back.
Voila! You have yourself a true unit test with FxCop custom rules (or as close as possible to one..).