动态生成代码的代码覆盖,分析和分析

时间:2023-01-18 23:16:25

I have a demo project, which creates an assembly and uses it. I also can debug the injected code. But if I run coverage, analysis or profiling, it is counted, but I want to measure it.

我有一个演示项目,它创建一个程序集并使用它。我也可以调试注入的代码。但是,如果我进行覆盖,分析或分析,它会被计算,但我想测量它。

Code:

码:

CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = false; // debug enabled                
parameters.OutputAssembly = "DynamicCode.dll"; // if specified creates the DLL
parameters.IncludeDebugInformation = true;
CompilerResults results = icc.CompileAssemblyFromFile(parameters, "InjectedCode.cs.txt");

I create the DLL to check the generated IL code. I can debug the code in VS. But when I run coverage, the generated assembly is simply missed, if I use TEMP directory, or if I output the DLL (like above) NO FILE is included in the coverage (so not even the main assembly).

我创建DLL来检查生成的IL代码。我可以在VS中调试代码。但是当我运行coverage时,如果我使用TEMP目录,或者如果我输出DLL(如上所述),那么生成的程序集就会被遗漏,因此覆盖范围内不包含任何文件(因此甚至不包括主程序集)。

When I run profiling, I can only see the invoke (reflection), but nothing about the generated code. When I do analysis (I have some errors in the injected code, e.g not used locals, and ofc analysis for everything), no problems are reported from the injected code. The injected code:

当我运行分析时,我只能看到调用(反射),但没有看到生成的代码。当我进行分析时(我在注入的代码中有一些错误,例如没有使用本地,以及所有内容的ofc分析),注入的代码没有报告任何问题。注入的代码:

namespace CodeInjection
{
    public static class DynConcatenateString
    {
        public static string Concatenate(string s1, string s2){
           //  System.Diagnostics.Debugger.Break(); // break here for debugger and also test comment output
            int a = 1+2+3+4+5; // complicated math
            int b = a+2;
            int c = 0;

            return s1 + " !"+b+"! " + s2;
        }
    }
}

I would like to use coverage, profiling and analysis on the generated code (mainly coverage).

我想对生成的代码(主要是覆盖范围)使用覆盖,分析和分析。

2 个解决方案

#1


1  

Ok code coverage in VS 2012 does not have full support for dynamically generated code.

VS 2012中的Ok代码覆盖率不完全支持动态生成的代码。

You can run our analyze command to see that your module has been skipped for this very same reason or is it because of a missing symbol/p

您可以运行我们的analyze命令,看看您的模块是否因为同样的原因而被跳过,或者是因为缺少符号/ p

#2


0  

In your project, add a new xml file and name it dynamic.runsettings.

在项目中,添加一个新的xml文件并将其命名为dynamic.runsettings。

It should contain the following:

它应包含以下内容:

    <?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
        <Configuration>
          <CodeCoverage>
            <ModulePaths>
<!--
About include/exclude lists:
Empty "Include" clauses imply all; empty "Exclude" clauses imply none.
Each element in the list is a regular expression (ECMAScript syntax).
An item must first match at least one entry in the include list to be included.
Included items must then not match any entries in the exclude list to remain included.
It is considered an error to exclude all items from instrumentation as no data would be collected.
-->
              <Include>
                <!-- <ModulePath>.*\\UnitTestProject1\.dll</ModulePath> -->
              </Include>
              <Exclude>
                <ModulePath>.*CPPUnitTestFramework.*</ModulePath>
              </Exclude>
            </ModulePaths>
            <UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
            <AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
            <CollectFromChildProcesses>True</CollectFromChildProcesses>
            <CollectAspDotNet>False</CollectAspDotNet>
<!--
Additional paths to search for symbol files. Symbols must be found for modules to be instrumented.
If symbols are alongside the binaries, they are automatically picked up. Otherwise specify the here.
Note that searching for symbols increases code coverage runtime. So keep this small and local.
<SymbolSearchPaths>
  <Path>C:\Users\User\Documents\Visual Studio 11\Projects\ProjectX\bin\Debug</Path>
  <Path>\\mybuildshare\builds\ProjectX</Path>
</SymbolSearchPaths>
-->
            <Functions>
              <Exclude>
                <Function>^std::.*</Function>
                <Function>^ATL::.*</Function>
                <Function>.*::__GetTestMethodInfo.*</Function>
                <Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
                <Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
                <Function>.*::YOU_CAN_ONLY_DESIGNATE_ONE_.*</Function>
              </Exclude>
            </Functions>
            <Attributes>
              <Exclude>
                <Attribute>^System.Diagnostics.DebuggerHiddenAttribute$</Attribute>
                <Attribute>^System.Diagnostics.DebuggerNonUserCodeAttribute$</Attribute>
                <Attribute>^System.Runtime.CompilerServices.CompilerGeneratedAttribute$</Attribute>
                <Attribute>^System.CodeDom.Compiler.GeneratedCodeAttribute$</Attribute>
                <Attribute>^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$</Attribute>
              </Exclude>
            </Attributes>
            <Sources>
              <Exclude>
                <Source>.*\\atlmfc\\.*</Source>
                <Source>.*\\vctools\\.*</Source>
                <Source>.*\\public\\sdk\\.*</Source>
                <Source>.*\\microsoft sdks\\.*</Source>
                <Source>.*\\vc\\include\\.*</Source>
              </Exclude>
            </Sources>
            <CompanyNames>
              <Exclude>
                <CompanyName>.*microsoft.*</CompanyName>
              </Exclude>
            </CompanyNames>
            <PublicKeyTokens>
              <Exclude>
                <PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
                <PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
                <PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
                <PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
                <PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
                <PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
                <PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
              </Exclude>
            </PublicKeyTokens>
          </CodeCoverage>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

Save that. What's special about this file is the CodeCoverage\ModulePaths\Include section has its ModulePath child commented out. This will now include ANY dlls it finds in code coverage.

保存。这个文件的特别之处在于CodeCoverage \ ModulePaths \ Include部分已将其ModulePath子项注释掉。这将包括它在代码覆盖中找到的任何dll。

Now Click on Test -> Test Settings -> Select Test Settings File and specify the dynamic.runsettings file. Your code coverage will now use this custom settings file.

现在单击Test - > Test Settings - > Select Test Settings File并指定dynamic.runsettings文件。您的代码覆盖率现在将使用此自定义设置文件。

Click on Analyze Code Coverage and run whichever tests you'd like. You should see your DynamicCode.dll show up in your coverage results (I have obscured my workstation name below):

单击“分析代码覆盖率”并运行您想要的任何测试。你应该看到你的DynamicCode.dll出现在你的报道结果中(我在下面模糊了我的工作站名称):

动态生成代码的代码覆盖,分析和分析

Note that I've added a new method to the .cs.txt file called BONK and it (correctly) shows up as 100% uncovered.

请注意,我在.cs.txt文件中添加了一个名为BONK的新方法,它(正确地)显示为100%未覆盖。

#1


1  

Ok code coverage in VS 2012 does not have full support for dynamically generated code.

VS 2012中的Ok代码覆盖率不完全支持动态生成的代码。

You can run our analyze command to see that your module has been skipped for this very same reason or is it because of a missing symbol/p

您可以运行我们的analyze命令,看看您的模块是否因为同样的原因而被跳过,或者是因为缺少符号/ p

#2


0  

In your project, add a new xml file and name it dynamic.runsettings.

在项目中,添加一个新的xml文件并将其命名为dynamic.runsettings。

It should contain the following:

它应包含以下内容:

    <?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
        <Configuration>
          <CodeCoverage>
            <ModulePaths>
<!--
About include/exclude lists:
Empty "Include" clauses imply all; empty "Exclude" clauses imply none.
Each element in the list is a regular expression (ECMAScript syntax).
An item must first match at least one entry in the include list to be included.
Included items must then not match any entries in the exclude list to remain included.
It is considered an error to exclude all items from instrumentation as no data would be collected.
-->
              <Include>
                <!-- <ModulePath>.*\\UnitTestProject1\.dll</ModulePath> -->
              </Include>
              <Exclude>
                <ModulePath>.*CPPUnitTestFramework.*</ModulePath>
              </Exclude>
            </ModulePaths>
            <UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
            <AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
            <CollectFromChildProcesses>True</CollectFromChildProcesses>
            <CollectAspDotNet>False</CollectAspDotNet>
<!--
Additional paths to search for symbol files. Symbols must be found for modules to be instrumented.
If symbols are alongside the binaries, they are automatically picked up. Otherwise specify the here.
Note that searching for symbols increases code coverage runtime. So keep this small and local.
<SymbolSearchPaths>
  <Path>C:\Users\User\Documents\Visual Studio 11\Projects\ProjectX\bin\Debug</Path>
  <Path>\\mybuildshare\builds\ProjectX</Path>
</SymbolSearchPaths>
-->
            <Functions>
              <Exclude>
                <Function>^std::.*</Function>
                <Function>^ATL::.*</Function>
                <Function>.*::__GetTestMethodInfo.*</Function>
                <Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
                <Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
                <Function>.*::YOU_CAN_ONLY_DESIGNATE_ONE_.*</Function>
              </Exclude>
            </Functions>
            <Attributes>
              <Exclude>
                <Attribute>^System.Diagnostics.DebuggerHiddenAttribute$</Attribute>
                <Attribute>^System.Diagnostics.DebuggerNonUserCodeAttribute$</Attribute>
                <Attribute>^System.Runtime.CompilerServices.CompilerGeneratedAttribute$</Attribute>
                <Attribute>^System.CodeDom.Compiler.GeneratedCodeAttribute$</Attribute>
                <Attribute>^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$</Attribute>
              </Exclude>
            </Attributes>
            <Sources>
              <Exclude>
                <Source>.*\\atlmfc\\.*</Source>
                <Source>.*\\vctools\\.*</Source>
                <Source>.*\\public\\sdk\\.*</Source>
                <Source>.*\\microsoft sdks\\.*</Source>
                <Source>.*\\vc\\include\\.*</Source>
              </Exclude>
            </Sources>
            <CompanyNames>
              <Exclude>
                <CompanyName>.*microsoft.*</CompanyName>
              </Exclude>
            </CompanyNames>
            <PublicKeyTokens>
              <Exclude>
                <PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
                <PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
                <PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
                <PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
                <PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
                <PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
                <PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
              </Exclude>
            </PublicKeyTokens>
          </CodeCoverage>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

Save that. What's special about this file is the CodeCoverage\ModulePaths\Include section has its ModulePath child commented out. This will now include ANY dlls it finds in code coverage.

保存。这个文件的特别之处在于CodeCoverage \ ModulePaths \ Include部分已将其ModulePath子项注释掉。这将包括它在代码覆盖中找到的任何dll。

Now Click on Test -> Test Settings -> Select Test Settings File and specify the dynamic.runsettings file. Your code coverage will now use this custom settings file.

现在单击Test - > Test Settings - > Select Test Settings File并指定dynamic.runsettings文件。您的代码覆盖率现在将使用此自定义设置文件。

Click on Analyze Code Coverage and run whichever tests you'd like. You should see your DynamicCode.dll show up in your coverage results (I have obscured my workstation name below):

单击“分析代码覆盖率”并运行您想要的任何测试。你应该看到你的DynamicCode.dll出现在你的报道结果中(我在下面模糊了我的工作站名称):

动态生成代码的代码覆盖,分析和分析

Note that I've added a new method to the .cs.txt file called BONK and it (correctly) shows up as 100% uncovered.

请注意,我在.cs.txt文件中添加了一个名为BONK的新方法,它(正确地)显示为100%未覆盖。