使用反射解析函数/方法内容

4

我的单元测试框架由TestFixtures、TestMethods和Actions组成。Action是TestMethod内的一个额外小容器,Action来自我们公司编写的内部Dll。Actions在方法中被使用,例如:

[Test]
void TestMethod1()
{
    Run(new Sleep { Seconds = 10 } );
}

我需要编写一个应用程序,从DLL中收集有关夹具,测试和操作的所有信息。我已经发现了如何使用类型/方法属性通过反射枚举测试夹具和测试方法。

但是我不知道如何枚举测试方法内部的操作。

请问您能帮忙吗?是否有可能使用反射完成这个任务?

更新: 请查看被接受的答案。它是真的很棒的库。如果您对我如何为夹具、测试和操作创建实体模型并以MVVM方式将其绑定到TreeView感兴趣,也可以在这里查看 (WPF:逐步教程中MVVM绑定TreeView的方式)。

3个回答

3

在一定程度上是可以的。

反编译将给出方法体,然后您需要反汇编IL以读取方法体并获取您想要的任何信息。

var bytes = mi.GetMethodBody().GetILAsByteArray();

可能的反编译工具之一是Cecil

查看遍历c#方法和分析方法体以获取更多链接。


0

不要使用反射,为什么不自己编写一个方法来记录所有操作的执行情况呢。

void ExecuteAction(Action action)
{
   //Log TestFixture, TestMethod, Action

   //Execute actual action
}

[Test]
void TestMethod1()
{
    ExecuteAction(Run(new Sleep { Seconds = 10 } ));
}

ExecuteAction方法可以在基类或辅助类中


谢谢回答。你是指像:每个动作之前,每个动作之后等函数吗?但这不适合。我有能力在运行时记录正在运行的所有操作。但我必须从DLL中收集所有信息,而不是在运行时收集。 - trickbz

0

感谢Alexei Levenkov!终于我找到了一个使用您的提示的解决方案。分享一下。唯一需要做的事情是->从https://github.com/jbevain/mono.reflection下载并引用Mono.Reflection.dll。

using System;
using System.Linq;
using System.Reflection;
using MINT;
using MbUnit.Framework;
using Mono.Reflection;

namespace TestDll
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            const string DllPath = @"d:\SprinterAutomation\Actions.Tests\bin\x86\Debug\Actions.Tests.dll";
            Assembly assembly = Assembly.LoadFrom(DllPath);

            // enumerating Fixtures
            foreach (Type fixture in assembly.GetTypes().Where(t => t.GetCustomAttributes(typeof(TestFixtureAttribute), false).Length > 0)) 
            {
                Console.WriteLine(fixture.Name);
                // enumerating Test Methods
                foreach (var testMethod in fixture.GetMethods().Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Length > 0))
                {
                    Console.WriteLine("\t" + testMethod.Name);
                    // filtering Actions
                    var instructions = testMethod.GetInstructions().Where(
                        i => i.OpCode.Name.Equals("newobj") && ((ConstructorInfo)i.Operand).DeclaringType.IsSubclassOf(typeof(BaseAction)));

                    // enumerating Actions!
                    foreach (Instruction action in instructions)
                    {
                        var constructroInfo = action.Operand as ConstructorInfo;
                        Console.WriteLine("\t\t" + constructroInfo.DeclaringType.Name);
                    }
                }
            }

        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接