4

NUnit インターフェイスにハッキングしようとするのはこれが初めてで、いくつかの問題に直面しています。

これは私が達成しようとしているものです:

  • 文字列入力のセットをコード ファイルとして取得し、それらをアセンブリにコンパイルします。
  • このコードでテストを識別して実行するために、インメモリ アセンブリを取得して NUnit に渡します。

これは私がこれまでに持っているものです

/// <summary> Validates whether the code files are valid </summary>
public string Validate(string[] codefiles)
{
    // To avoid NullReferenceException within NUnit
    // don't know why this is needed!
    TestExecutionContext.CurrentContext.TestPackage
        = new TestPackage("PersonTest");

    var assembly = BuildAssembly(codefiles);
    TestSuite suite = new TestAssembly(assembly, "PersonTest");
    var result = suite.Run(new NullListener(), TestFilter.Empty);
    return result.IsSuccess ? string.Empty : result.Message;
}

/// <summary> Builds an assembly </summary>
private static Assembly BuildAssembly(string[] code)
{
    var compilerparams = new CompilerParameters(new[] {"nunit.framework.dll"})
    {
        GenerateExecutable = false,
        GenerateInMemory = true
    };
    var results = new CSharpCodeProvider()
        .CompileAssemblyFromSource(compilerparams, code);

    if (!results.Errors.HasErrors) return results.CompiledAssembly;

    throw new Exception(GetErrors(results));
}

これらは、コンパイルしようとしている 2 つの文字列です (上記の検証メソッドに 2 つの要素を含む文字列配列として送信することにより)

private const string File1 = @"
    public class Person 
    {
        public string Name {get;set;}

        public Person(string name)
        {
            Name = name;
        }
    }";

private const string ProperInput = @"
    using NUnit.Framework;

    [TestFixture]
    public class PersonTest
    {
        [Test]
        public void CheckConstructor()
        {
            var me = new Person(""Roopesh Shenoy"");
            Assert.AreEqual(""Roopesh Shenoy"", me.Name);
        }
    }";

問題:

コンパイルは正常に行われます。生成されたアセンブリには、これら 2 つのタイプがあります。また、参照されたアセンブリに nunit.framework.dll を渡さないと、(動的にコンパイルする場合) コンパイル例外が発生するため、TestFixture/Test アドリブも認識されることを意味します。

ただし、TestAssembly をデバッグすると、テスト カウントがゼロと表示されます。したがって、テストの成功または失敗を示す代わりに、決定的でないことを示し、基本的に何もしません。

NUnit コードベースを調べてみましたが、まだ良い結論に達していません。便利なメソッドのほとんどは、アセンブリがファイル システム上にあることを想定しているため、これを行う方法を正確に理解しようとしています。何か案は?

4

2 に答える 2

2

NUnit は実行時に AppDomain の作成を行いますが、これをすべて動的に実行するとそれが壊れて、依存関係がないためにテストが表示されないのではないでしょうか?

于 2012-11-03T17:29:55.773 に答える
1

ああ、うまくいく!

いくつかの手順(フィクスチャが個別に識別されてアセンブリに追加される)と、最初は「InstallBuiltIns」メソッドの呼び出しがありませんでした。これで動作し、次のようになります。

//this is needed only once
CoreExtensions.Host.InstallBuiltins();

var assembly = BuildAssembly(codefiles.ToArray());

// to avoid NullReferenceException - don't know why this is needed!
TestExecutionContext.CurrentContext.TestPackage
    = new TestPackage(assembly.GetName().FullName);

var suite = GetTestSuiteFromAssembly(assembly);
return suite.Run(new NullListener(), TestFilter.Empty);

どこ:

/// <summary>
/// Converts a given assembly containing tests to a runnable TestSuite
/// </summary>
protected static TestSuite GetTestSuiteFromAssembly(Assembly assembly)
{
    var treeBuilder = new NamespaceTreeBuilder(
        new TestAssembly(assembly, assembly.GetName().FullName));
    treeBuilder.Add(GetFixtures(assembly));
    return treeBuilder.RootSuite;
}

/// <summary>
/// Creates a tree of fixtures and containing TestCases from the given assembly
/// </summary>
protected static IList GetFixtures(Assembly assembly)
{
    return assembly.GetTypes()
        .Where(TestFixtureBuilder.CanBuildFrom)
        .Select(TestFixtureBuilder.BuildFrom).ToList();
}

BuildAssemblyは以前と同じです。NUnitのロジックの一部を繰り返さなければならなかった唯一の理由は、何らかの理由でこれらがNUnitコードベース内でプライベートであったことです。

于 2012-11-03T15:33:23.267 に答える