Unity/C#, NUnit Parallelizable attribute

Viewed 308

I'm using Unity 2019.4.4f1 with NUnit 3.5.

I have set up a very simple parallel test between methods to see if it actually works, but they run in sync. I've been looking into NUnit parallel testing for some days, but I feel like I'm missing some very obvious thing.

using NUnit.Framework;
using System.Threading;

namespace NUnitTest
{
    [TestFixture]
    public class ParallelTest
    {
        [Test]
        [Parallelizable]
        public void Test01()
        {
            Debug.Log("Test 1 started");
            Thread.Sleep(2000);
            Debug.Log("Test 1 ended");
            Assert.IsTrue(true);
        }

        [Test]
        [Parallelizable]
        public void Test02()
        {
            Debug.Log("Test 2 started");
            Thread.Sleep(2000);
            Debug.Log("Test 2 ended");
            Assert.IsTrue(true);
        }
    }
}

In TestRunner, I run ParallelTest to run them both at the same time. I'd imagine the total runtime of ParallelTest should be near 2 seconds, but instead it's 4 seconds.

Any advice will be appreciated.

2 Answers

Unity has adapted the NUnit framework quite a bit. If there's one thing that Unity applications have never got along with, that would be async code.

The NUnit framework runs tests in parallel using multi-threaded test execution, which I imagine is the first thing Unity removed when creating their adaptation of the test runner.

If your code can be moved out of Unity and then imported via a DLL then I recommend you do that. That way your Unit Tests can use the raw NUnit framework! It's a pattern that I've adopted for all of my projects.

Long story short, I don't think you can.

According to a Unity technology employee, this is still not supported even in recent version. But the answer he gave adds more details.

It is currently true that we don't support running parallelised tests inside Unity, because the custom runner we developed (to support things like [UnityTest]) doesn't have it implemented.

[...] the UnityEngine API has a reliance on the main thread - calling Unity APIs from background threads will (almost) always throw - so it hasn't been a priority to support this, as it would only be usable for tests that don't call Unity APIs. (Async doesn't help, because the synchronisation context in Unity only executes async tasks on the main thread, specifically because of this restriction on the API).

Related