4

My question is similar to this one: Junit: splitting integration test and Unit tests. However, my question regards NUnit instead of: JUnit. What is the best way to distinguish between Unit Tests and Integration Tests inside a test class? I was hoping to be able to do something like this:

[TestFixture]
    public class MyFixture
    {
        [IntegrationTest]
        [Test]
        public void MyTest1()
        {
        }

        [UnitTest]
        [Test]
        public void MyTest1()
        {
        }
    }

Is there a way to do this with NUnit? Is there a better way to dot this?

w0051977
  • 15,099
  • 32
  • 152
  • 329
  • I did something like that. I created two attributes that set the category of the test which allowed me to separate unit and integration tests – Nkosi Jan 24 '18 at 15:03
  • @Nkosi, I guess there is no built in attributes? Did it help you at all? – w0051977 Jan 24 '18 at 15:04
  • Well it works for me. There was no built in way so I created my own – Nkosi Jan 24 '18 at 15:04
  • @Nkosi, did you have unit tests and integration tests inside the same test class? – w0051977 Jan 24 '18 at 15:05
  • Did it work better when they were together? May I ask what size of system it was? I am trying to establish whether this would work with a large enterprise app or whether it will just introduce unnecessary complexity. – w0051977 Jan 24 '18 at 15:09

4 Answers4

9

Personally I've found it better to keep them in separate assemblies. You can use a convention, such as name.Integration.Tests and name.Tests (or whatever your team prefers).

Either assemblies or attributes work fine for CI servers like TeamCity. The pain with the attribute approach tends to show up in IDE test runners. I want to be able to quickly run only my unit tests. With separate assemblies, it's easy - select the appropriate test project and run tests.

TrueWill
  • 25,132
  • 10
  • 101
  • 150
  • Thanks +1 for the assembly suggestion. The separate namespaces make them easier to identify and as you say integration with external tools is better. – w0051977 Jan 24 '18 at 15:32
  • Can I confirm that when you say integration test; you mean a test where mocks are not used. For example, see the code here: https://github.com/jbogard/presentations/blob/master/WickedDomainModels/After/Model/Member.cs. In my test - if I supplied concrete implementations of: OfferType and IValueCalculator, then this would be an integration test? – w0051977 Jan 24 '18 at 15:34
  • I was wondering. Currently flagging unit tests with the unit category - `xunit` - [Trait("Test Type", "Unit")] or [Trait("Unit Test", "")]. Was thinking about going the separate assembly route thinking ahead to running tests on check ins. – Andez Jan 24 '18 at 16:39
  • @w0051977 I tend to use "integration test" to mean anything that either runs slowly or is impure (has side effects or isn't deterministic). A "unit" test could still test a couple of classes together. – TrueWill Jan 25 '18 at 02:45
  • 1
    In Visual Studio 2022 you can now do that using the [Category("Integration")] approach and select them from within the Test Explorer filter options without separating them out into separate assemblies. – user2960136 Jul 22 '22 at 12:15
1

The Category Attribute might help you do this.

https://github.com/nunit/docs/wiki/Category-Attribute

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [Test]
    [Category("Unit")]
    public void VeryLongTest()
    { /* ... */ }
}
LoflinA
  • 350
  • 4
  • 19
1

This answer shares some details with a few other answers, but I'd like to put the question in a slightly different perspective.

The design of TestFixtures is such that every test gets the same setup. To use TestFixtures correctly, you should divide your tests in such a way that all the tests with the same setup end up in the same test class. This is how almost every xunit framework is designed to be used and you always get better results when you use software as it is designed to be used.

Since Integration and Unit tests are not likely to share the same setup, this would naturally lead to putting them in a separate class. By doing that, you can group all integration tests under a namespace that makes them easy to run independently.

Even better, as another answer suggests, put them in a separate assembly. This works much better with most CI builds, since failure of an integration test may be more easily distinguished from failure of an integration test. Also, use of a separate assembly eliminates all the complication of using categories or special attributes.

Charlie
  • 12,928
  • 1
  • 27
  • 31
0

Do not have them in the same class, either split them down into folders within your test assembly or split them into two separate test assemblies.

In the long run this will be far easier to manage especially if you use tools like NCrunch.

ianrathbone
  • 2,334
  • 2
  • 15
  • 16