I have a feeling we're going to be spending a few days answering all the inevitable questions that come up about xUnit.net. :)
A common theme of comments comes about the simplicity of the framework, some seeing this as a positive and some as a negative. This is definitely a design criteria for us. We're not trying to replicate every single attribute and assertion that the existing frameworks have, but rather use 5 years of experience to help us design something slightly different and new.
The first set come from Roy Osherove. Here are his questions, along with our answers:
There is no Assert.Fail (overlooked? I find this very usable in some instances) We didn't overlook this, actually. I find Assert.Fail is a crutch which implies that there is probably an assertion missing. Sometimes it's just the way the test is structured, and sometimes it's because Assert could use another assertion. We've seen Assert grow over time in many of the unit testing frameworks, so rather than letting Assert.Fail be a crutch, it's better to hear about what those missing methods on Assert might be. I've used Assert.Fail a lot in NUnit, but I haven't missed it once in xUnit.net.
There is currently only a console runner. But there is already shipping TestDriven.NET support as part of the download! just run xunit.tdnet.installer.exe that is next to the xunit.framework.dll This, too, was a conscious decision. Those are the two runners we use most (console for automated builds, and in-Visual-Studio test runs with TD.NET during development). We have two open issues on the xUnit.net issue tracker about adding a GUI runner and a Resharper runner, to see how many votes they'll get. We'd also encourage people to open bugs for other runners that might be useful.
Assert.Equals is deprecated and ou are instructed to use a generic version of Assert.Equal (without the 's') / I think this is a problem because generics make the Assert code longer to write and read while giving little contribution to the developer of the tests. Actually, the "Equals" method is part of Object, and it's not an assertion. We added the deprecated attribute to it so nobody would accidentally call it. Plus, the generic version of Equal does not actually require you to provide the type if it can be inferred, as I talked about in my last post.
There is no built in Mocking framework There's really no reason to build in a mocking framework, as they shouldn't be tied to any specific unit testing framework. Myself, I prefer to hand write stubs (though I have used both RhinoMocks and NMock).
Assert.Equal on two strings, if it fails, does not add that nice little touch of visual that Nunit has that shwos you with an ascii arrow "----^" where the strings differ first Yep, we could add this. Write a feature request! :)
There is no Setup and teardown This is one of those controversial decisions that will probably really get people talking. You can use constructors and IDisposable.Dispose() where you would've used SetUp and TearDown, so it's not that the functionality is completely gone. However, we do feel strongly against using it (and instead using the cross-cutting concerns system that we've added for extensibility purposes instead for common things like auto-rollback on database tests).
There is still no solution for what happens if mutiple custom test attributes need to be run in a specific order. True, we don't address this, and we would prefer not to. The cross-cutting concerns attributes should operate independent of one another; if there is a dependency, then wrap up the combined behavior into a new, single attribute. The complexity involved with setting ordering is very unlikely to be worth the effort to understand and implement it.
No Expected exception attribute. use try-catch or Assert.Throws, I find that less readable. Experience has really borne this one out for me. Consider, for example, your typical mock framework which requires you to call things like "mocks.VerifyAllExpectations()". When using ExpectedException, it's very easy to overlook the fact that this method never gets called, and your mocks aren't necessarily providing you with the safety you think they are. In addition, Assert.Throws allows you to inspect the exception object and run further asserts on it, something that ExpectedException does not do.
From looking at the source code, it shoudl be able to also run NUnit tests (backwards compatible) We're working on separate Wiki content (and a blog post) which will address specifically how to migrate from NUnit to xUnit.net using the [RunWithNUnit] attribute.
Lots of great feedback so far. Keep it coming, everybody!