在Mono中运行Visual Studio 2008 C#(基于MSTest.exe)单元测试

时间:2009-08-08 21:01:13

标签: visual-studio-2008 unit-testing mono mstest

我正在使用VS2008开发一个我正在Mono下开始测试的项目。 有很多使用VS单元测试框架编写的单元测试,有没有一个工具可以让我在Mono中运行它们?

谢谢,

2 个答案:

答案 0 :(得分:2)

根据您使用的功能,它可能很简单或很难。您可以使用命名空间/类型别名来使用另一个类库来执行断言和属性。我编写了手动运行测试的控制台程序 - 当然我可以访问vs命名空间和程序集。

对于mono - 我的建议是完全使用另一个测试系统,因为你自己使用system.reflection命名空间来加载程序集,反映属性并按需要执行,这将是乏味的。

例如:

Pseudo code:

var assembly = loadAsembly(....)
foreach(type in assembly.types) {
 if(type is static class and had method with AssemblyInitialiseAttrubute)){
    InvokeTheMethod(method);
 }
}

foreach(type in assembly.types) {
 if(type is not class and had method with TestClass)){
    InvokeTheMethod(method);
 }
 foreach(method in type with ClassinitialiseAttribute)
}
... etc

答案 1 :(得分:0)

我编写了以下代码,它在Mono上运行良好。该代码不依赖于Visual Studio测试专用DLL。令人惊讶的是,它在Mone(在我的PC上的VirtualBox上运行)上运行的速度比在Visual Studio中快一些。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace drvrapp {
    public class TestRunner {
        // assembly file (e.g. MyTestAssembly.dll) which should be in the same directory 
        public static void TestDll(string assemblyFile) {
            string symbolsFile = Path.GetFileNameWithoutExtension(assemblyFile) + ".pdb";

            byte[] assemblyBytes = File.ReadAllBytes(assemblyFile);
            byte[] symbolsBytes = File.ReadAllBytes(symbolsFile);

            Assembly assembly = Assembly.Load(assemblyBytes, symbolsBytes);

            foreach (Type type in assembly.GetTypes())
                if (HasAttribute(type, "TestClass"))
                    foreach (MethodInfo method in type.GetMethods())
                        if (HasAttribute(method, "TestMethod"))
                            RunTest(method);
        }

        private static void RunTest(MethodInfo method) {
            Console.WriteLine("------------------------------------------------------------------------------------------");
            Console.Write("Running {0}.{1}...", method.DeclaringType.Name, method.Name);

            if (HasAttribute(method, "Ignore")) {
                Console.WriteLine("IGNORED");
                return;
            }

            try {
                Type testType = method.DeclaringType;
                object typeClassInstance = Activator.CreateInstance(testType);

                RunInitializeOrCleanup(typeClassInstance, "TestInitialize");
                method.Invoke(typeClassInstance, null);
                RunInitializeOrCleanup(typeClassInstance, "TestCleanup");

                Console.WriteLine("PASSED");
            } catch (Exception e) {
                Console.WriteLine();
                Console.WriteLine(e);
            }
        }

        private static void RunInitializeOrCleanup(object instance, string attribute) {
            MethodInfo method = instance.GetType().GetMethods().SingleOrDefault(x => HasAttribute(x, attribute));
            if (method != null)
                method.Invoke(instance, null);
        }

        private static bool HasAttribute(MemberInfo info, string attributeName) {
            return info.GetCustomAttributes(false).Any(x => x.GetType().Name == attributeName + "Attribute");
        }
    }
}

using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.IO; namespace drvrapp { public class TestRunner { // assembly file (e.g. MyTestAssembly.dll) which should be in the same directory public static void TestDll(string assemblyFile) { string symbolsFile = Path.GetFileNameWithoutExtension(assemblyFile) + ".pdb"; byte[] assemblyBytes = File.ReadAllBytes(assemblyFile); byte[] symbolsBytes = File.ReadAllBytes(symbolsFile); Assembly assembly = Assembly.Load(assemblyBytes, symbolsBytes); foreach (Type type in assembly.GetTypes()) if (HasAttribute(type, "TestClass")) foreach (MethodInfo method in type.GetMethods()) if (HasAttribute(method, "TestMethod")) RunTest(method); } private static void RunTest(MethodInfo method) { Console.WriteLine("------------------------------------------------------------------------------------------"); Console.Write("Running {0}.{1}...", method.DeclaringType.Name, method.Name); if (HasAttribute(method, "Ignore")) { Console.WriteLine("IGNORED"); return; } try { Type testType = method.DeclaringType; object typeClassInstance = Activator.CreateInstance(testType); RunInitializeOrCleanup(typeClassInstance, "TestInitialize"); method.Invoke(typeClassInstance, null); RunInitializeOrCleanup(typeClassInstance, "TestCleanup"); Console.WriteLine("PASSED"); } catch (Exception e) { Console.WriteLine(); Console.WriteLine(e); } } private static void RunInitializeOrCleanup(object instance, string attribute) { MethodInfo method = instance.GetType().GetMethods().SingleOrDefault(x => HasAttribute(x, attribute)); if (method != null) method.Invoke(instance, null); } private static bool HasAttribute(MemberInfo info, string attributeName) { return info.GetCustomAttributes(false).Any(x => x.GetType().Name == attributeName + "Attribute"); } } }