[英]Custom Rule in FxCop to only apply to methods called by particular type's method
[英]FxCop rule around ensuring a certain method accepting a lambda is called first in a test
使用自定义FXCop规则,我想确保在每个单元测试的顶部都调用一个方法,并且确保所有单元测试代码都是传递给该方法的Action的一部分。 本质上我想要这样:
[TestMethod]
public void SomeTest()
{
Run(() => {
// ALL unit test code has to be inside a Run call
});
}
确保确实调用Run并不难:
public override void VisitMethod(Method member)
{
var method = member as Method;
if (method == null || method.Attributes == null)
return;
if (method.Attributes.Any(attr => attr.Type.Name.Name == "TestMethodAttribute") &&
method.Instructions != null)
{
if (!method.Instructions.Any(i => i.OpCode == OpCode.Call || i.Value.ToString() == "MyNamespace.Run"))
{
this.Problems.Add(new Problem(this.GetResolution(), method.GetUnmangledNameWithoutTypeParameters()));
}
base.VisitMethod(method);
}
诀窍是确保测试的顶部没有Run语句之前的内容。 在过去的几个小时中,我花了很多时间在指令集上研究模式,并试图了解如何在代码中有效地使用Body.Statements集。
这也可以作为一个简单的IL问题提出。 我想知道一个可以验证的特定模式,我可以接受它:
public void SomeTest()
{
Run(() => {
// Potentially lots of code
});
}
但是将拒绝以下任何一个:
public void SomeTest()
{
String blah = “no code allowed before Run”;
Run(() => {
// Potentially lots of code
});
}
public void SomeTest()
{
Run(() => {
// Potentially lots of code
});
String blah = “no code allowed after Run”;
}
尽管您可以使用Method.Body
访问类似表达式树的结构, Method.Body
我可能还是会仔细研究一下指令,因为我发现它与过去的常见情况(例如,内联数组初始化)相混淆。
C#如何生成lambda表达式取决于lambda表达式访问的内容:
this
访问任何实例成员,则它将仅在this
上创建实例方法的委托。 您可能可以创建自己的评估堆栈并通过该方法跟踪值(我过去曾经做过,虽然很简单,并且代码很少,但并不是特别困难),但是我怀疑您可以实现“足够好只需执行以下规则即可:
System.Action
和编译器生成的类型。 Run
,并且必须恰好调用一次。 Run
的调用必须紧跟一个ret
指令(忽略它们之间可能出现的任意数量的nop
指令)。 Run
之后,任何分支指令都不能跳转到某个位置。 newobj
, call
, callvirt
, ldftn
, nop
, ret
, ldnull
_Locals
(这只是FxCop为局部变量插入的伪指令。) FxCop提供RuleUtilities.IsCompilerGenerated
来确定本地是否由编译器生成,但是它对字段没有帮助,我怀疑如果FxCop可以找到pdb文件,则仅对本地用户有用。 您可能会发现说“本地/字段/类型是编译器生成的,如果它的类型名称在C#中不是有效的标识符”会更容易说出来。
说了这么多,坚持所有测试都完全通过Run
方法Run
似乎有些武断。 如果目标是Run
方法提供通用的设置/拆卸逻辑,则可以通过nunit提供更好的方法。 强制人们应用您的动作属性比强制他们以特定方式编写测试要容易得多。
另外,您也可以编写罗斯林分析仪。 分析人员可以访问描述代码编写方式的语法树,而无需对IL和元数据进行结构反向工程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.