Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

unit testing - Why is the xUnit Runner not finding my tests

I have a xUnit.net Test as follows:

static class MyTestClass
{
    [Fact]
    static void MyTestMethod() 
    {
    }
}

The xUnit plugin for VS 2012 says:

No tests found to run.

TestDriven.net runs it fine but mentions something about Ad hoc:

1 passed, 0 failed, 0 skipped (see 'Task List'), took 0.47 seconds (Ad hoc)

TeamCity, xunit.gui.exe and xunit.console.exe and Visual Studio also can't find TestMethod

(I've got xunit.runner.visualstudio installed and VS is seeing some tests.)

What gives?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

TL;DR your Test Classes must be public (but your Test Methods can be private and/or static)


For reasons of efficiency, the xUnit authors have opted to not use BindingFlags.NonPublic when searching for Test Classes in the runner (the MSIL metadata tables don't index private(/internal) classes to the same degree hence there is a significant performance difference in the relative efficiency that Reflection can thus achieve).

As a result of the above, the fact that your class is private means it doesn't get picked up.

The fact that the Test Method is private and static is fine - xUnit by design since 1.0 has supported both those aspects.

Note that the Visual Studio xUnit Runner extension, xunit.console.exe (and the GUI), the xunit MSBuild task, Resharper and CodeRush are all consistent in honouring this (although arguably they [especially the latter two] could do more to flag when a Test Class (i.e. class [potentially indirectly] containing Fact-derived annoations) is private).

The reason TestDriven.net runs your test is that the Author of TestDriven.net has put great effort into making it Just Work. It internally uses a special Test Runner wrapper/shim (termed the Adhoc Runner) to run your test. Be aware that the method is actually not being run via the xUnit.net runner and hence any attributes you put on your test that have side effects will not be triggered.

Notably NUnit (and I'm pretty sure MSTest) do use private reflection [and hence pick up tests in private classes] which is probably why it never seemed an important thing for you to worry about before.

Note: A side effect / trick enabled by this is that you can make a Test Class private as a quick way of Skipping all tests in a Test Class [and any nested classes]. (Sadly the cases on this planet of this being used unintentionally vastly outnumber the intentional cases of this though!)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...