在powershell中检索NUnit自定义属性

Jir*_*Jir 3 powershell attributes nunit

假设您有一个包含NUnit测试的.dll文件,其中所有测试过程都具有该[Test]属性.记录了一些测试,这意味着它们被标记[Test, Description(...)].

我认为我可以使用PowerShell中的反射检索具有该[Test]属性和相关描述(如果有)的所有函数.

我试着看看我是否可以在下面看到所述属性:

$suite = [Reflection.Assembly]::ReflectionOnlyLoadFrom("D:\test_suite.dll")
[reflection.customattributedata]::GetCustomAttributes($suite)
Run Code Online (Sandbox Code Playgroud)

但我能看到的没有显示测试的痕迹:

AttributeType                Constructor                 ConstructorArguments        NamedArguments             
-------------                -----------                 --------------------        --------------             
System.Runtime.InteropSer... Void .ctor(System.String)   {"02cfdc16-5480-4bb6-890... {}                         
System.Diagnostics.Debugg... Void .ctor(DebuggingModes)  {(System.Diagnostics.Deb... {}                         
System.Reflection.Assembl... Void .ctor(System.String)   {"Copyright © Microsoft ... {}                         
System.Reflection.Assembl... Void .ctor(System.String)   {"1.0.0.0"}                 {}                         
System.Runtime.InteropSer... Void .ctor(Boolean)         {(Boolean)False}            {}                         
System.Runtime.CompilerSe... Void .ctor(Int32)           {(Int32)8}                  {}                         
System.Runtime.CompilerSe... Void .ctor()                {}                          {WrapNonExceptionThrows ...
System.Reflection.Assembl... Void .ctor(System.String)   {""}                        {}                         
System.Reflection.Assembl... Void .ctor(System.String)   {"Test_Test_Suite"}         {}                         
System.Reflection.Assembl... Void .ctor(System.String)   {""}                        {}                         
System.Reflection.Assembl... Void .ctor(System.String)   {""}                        {}                         
System.Reflection.Assembl... Void .ctor(System.String)   {"Microsoft"}               {}                         
System.Reflection.Assembl... Void .ctor(System.String)   {"Test_Test_Suite"}         {}
Run Code Online (Sandbox Code Playgroud)

我显然走错了路.任何提示?

Rob*_*und 5

问题是您正在查看程序集上的属性,而不是程序集中的方法.

要做到这一点,只需获取程序集中的类型,然后获取它们的方法,然后过滤这些类型,只获取具有TestAttribute而不是DescriptionAttribute的方法.

因此,首先,只需获取已经执行的程序集元数据:

$testSuite = [System.Reflection.Assembly]::ReflectionOnlyLoadFrom("c:\testsuite.dll")
Run Code Online (Sandbox Code Playgroud)

然后获取程序集中可用的方法:

$methods = $testSuite.GetTypes().GetMethods()
Run Code Online (Sandbox Code Playgroud)

如果有这些,请过滤掉具有TestAttribute的方法.你可能会以比这更好的方式确定TestAttribute的存在,例如给出你正在寻找或类似的确切属性名称,但我没有在我自己的样本中使用NUnit属性.

$testMethods = $methods | 
    Where { 
        $_.GetCustomAttributesData() | 
            Where { $_.AttributeType.FullName -like "*.TestAttribute" } 
    }
Run Code Online (Sandbox Code Playgroud)

当你这样做时,只需从中选择你想要的数据(我也包括DeclaringType,如果你不想在你的选择中删除它,只需删除它):

$testDocumentation = $testMethods | 
    Select DeclaringType, Name, @{
        Name = "Description"
        Expression = { 
            $descriptionAttribute = $_.GetCustomAttributesData() |
                Where { $_.AttributeType.FullName -like "*.DescriptionAttribute"}
            Write-Output $descriptionAttribute.ConstructorArguments[0].Value
        }
    }
Run Code Online (Sandbox Code Playgroud)

或者你可以在一行中完成所有这些,如果你是如此倾向:

[Reflection.Assembly]::ReflectionOnlyLoadFrom("$pwd\ClassLibrary2.dll").GetTypes().GetMethods() | 
    Where { $_.GetCustomAttributesData() | Where { $_.AttributeType.FullName -like "*.TestAttribute" } } | 
    Select DeclaringType, Name, @{
        Name = "Description"
        Expression = { 
            $descriptionAttribute = $_.GetCustomAttributesData() |
                Where { $_.AttributeType.FullName -like "*.DescriptionAttribute"}
            Write-Output $descriptionAttribute.ConstructorArguments[0].Value
        }
    } 
Run Code Online (Sandbox Code Playgroud)

使用我的小测试程序集,这导致以下输出:

DeclaringType                 Name                         Description                 
-------------                 ----                         -----------                 
TestSuite.TestClass1          FirstTest                    This is the first test
TestSuite.TestClass1          SecondTest                   This is my second test
TestSuite.TestClass1          ThirdTest                    This is my third test
Run Code Online (Sandbox Code Playgroud)