定制FxCop规则--检测Release版本中的TestCase

在使用NUnit进行开发的时候,TestCase是不可省的.通过TestCase,我们才可以保证所撰写的代码的正确性:)

但是由于在开发过程中是边写TestCase,边实现功能代码的,如果不注意的话,在最终的Release版本中可能会出现曾经写过的TestCase...这应该是在程序开发过程中尽量避免的:)
解决这个问题的方法有以下几种:
1,使用 #if DEBUG XXX #endif 标签.将所有的TestCase放到此标签中.这样当以Debug方式编译的时候,可以使用NUNit进行测试.当以Release方式编译的时候,其中的所有代码将会被忽略掉(相当于注释掉).这样就不会产生多余的代码了:)
2,将所有的TestCase放到单独的工程中.这样,功能代码将不可能包括测试代码,这样也可以避免上述问题..

在一个项目中,为了对所有的代码进行上述检查,如果用人工的方式来检查,那显然是不现实的.即然大家都是玩电脑的,那何不用电脑来检查了:)呵呵,对了,使用.NET下面的FxCop...

FxCop自带的Rules里面没有这样的规则,那我们得自定义一个Rule了:)

此Rule的工作流程如下:
1,得到此程序中所有的Class.
2,对每一个Class,得到其Attribute.
3,对每一个Attribute,判断是不是NUnit.Framework.TestFixtureAttribute.如果是,返回错误.

注:一定要是Release版本的程序,才可以起到真正的检测目的.

通过 定制FxCop规则示例之一:AvoidICloneableImplementation 这篇文章,我们可以学会怎么编写一个基本的FxCop的Rule...但只是文章中的东西是不能解决我们的这个问题的..我们来Google一下,看看有没有别的信息..
找到了这个:
Writing custom rules [using introspection] for FxCop 1.312 (from: James Geurts)
FxCop Custom Rule - Introspection Engine 3.12

注意这段:
The BaseIntrospectionRule  class  provides some overloaded versions of the Check() method. The available methods are: 

Check(Member member)
   
-  Useful  for  checking members of a  class . (Methods, Properties, Events, Delegates, etc)
Check(Module module)
   
-  Useful  for  checking assemblies.
Check(Parameter parameter)
   
-  Checks all parameters
Check(Resource resource)
   
-  Checks all resources (from .resx files)
Check(TypeNode type)
   
-  Checks types
Check(
string  namespaceName, TypeNodeList types) 
   
-  Checks types 

对于我们现在要编写的Rule而言,我们要使用第5个函数,即: Check(TypeNode type)
通过对TypeNode类的使用,我们可以发现他有 Attributes 这样一个属性,即可以获得此Class上的所有Attribute.
其类型是 AttributeList..
AttributeList中存放的是AttributeNode,不同于.NET FX中带的Attribute.即不能直接判断AttributeNode == Attribute.
幸好TypeNode提供了FullName属性.这个属性中存放的是实际类的全名.
即NUnit.Framework.TestFixtureAttribute类的TypeNode的FullName是 "NUnit.Framework.TestFixtureAttribute"

到这里,技术上的工作都搞定了..下面是代码实现
RuleInfo.xml
<? xml version="1.0" encoding="utf-8"  ?>  
< Rules  FriendlyName ="Avoid NUnit TestCase in Release Version" >
  
< Rule  TypeName ="AvoidNUnitTestCase"  Category ="Cnblogs.Rules"  CheckId ="hbifts000001" >
    
< Name > Avoid NUnit TestCases Implementation in Release Version </ Name >
    
< Description > NUnit TestCases must never be included in release versions. </ Description >
    
< Url > http://www.cnblogs.com/hbifts </ Url >
    
< Resolution > Type '{0}' Implements NUnit TestCases, which should avoid in release version.You should add #if DEGUG XXX #endif. </ Resolution >
    
< Email  />
    
< MessageLevel  Certainty ="99" > Error </ MessageLevel >
    
< FixCategories > Breaking </ FixCategories >
    
< Owner  />
  
</ Rule >
</ Rules >

AvoidNUnitTestCase.cs实现
     public   class  AvoidNUnitTestCase : BaseIntrospectionRule
    
{
        
public AvoidNUnitTestCase() : base("AvoidNUnitTestCase","Cnblogs.Rules.RuleInfo",typeof(AvoidNUnitTestCase).Assembly)
        
{
        }


        
public override ProblemCollection Check(TypeNode type)
        
{
            
if( DoesImplementConditionAttribute(type.Attributes)){
                Resolution resolution 
= GetResolution(RuleUtilities.Format(type));
                Problem problem 
= new Problem(resolution,type);
                Problems.Add(problem);
                
return Problems;
            }

            
return null;
        }


        
private bool DoesImplementConditionAttribute( AttributeList Lists )
        
{
            Log.WriteFile( Lists.Length.ToString());
            
for(int i=0;i<Lists.Length;i++){
                
if( Lists[i].Type.FullName.Equals("NUnit.Framework.TestFixtureAttribute")){
                    
return true;
                }

            }

            
return false;
        }

    }

编译成一个dll..加入到FxCop的Rules中,这样我们就可以很方便的每日Build后检测Release版本是否存在TestCase:)

All Happy~:)

你可能感兴趣的:(test)