Search Unity

TestRunnerApi: getting callbacks for playmode tests

Discussion in 'Testing & Automation' started by Martin_KageNova, Feb 28, 2020.

  1. Martin_KageNova

    Martin_KageNova

    Joined:
    Jul 30, 2019
    Posts:
    7
    I'm trying to run my tests from a C# script. For EditMode tests that's all well and good but I seem to have some trouble when doing the same for PlayMode tests. The tests do run, but none of the callbacks in my ICallbacks implementation get called.

    Also, if I try to run EditMode and PlayMode together (either by combining the two TestMode flag values, or by passing in two filter objects), it seems like only the edit mode tests are run. While that's weird, there's an easy workaround for this (just run them separately), but not being able to get any callbacks from PlayMode tests is an issue.

    Is this a known problem?

    Here's some example code:

    Code (CSharp):
    1.     public class TestsFromScript
    2.     {
    3.         public static void RunTests()
    4.         {
    5.             var testApi = ScriptableObject.CreateInstance<TestRunnerApi>();
    6.             testApi.RegisterCallbacks(new TestCallbacks());
    7.  
    8.             var playModeFilter = new Filter() { testMode = TestMode.PlayMode };
    9.             testApi.Execute(new ExecutionSettings(playModeFilter));
    10.         }
    11.  
    12.         private class TestCallbacks : IErrorCallbacks
    13.         {
    14.             public void OnError(string message)
    15.             {
    16.                 Debug.Log(message);
    17.             }
    18.  
    19.             public void RunFinished(ITestResultAdaptor result)
    20.             {
    21.                 Debug.Log("Tests finished");
    22.             }
    23.  
    24.             public void RunStarted(ITestAdaptor testsToRun)
    25.             {
    26.                 Debug.Log("Tests started");
    27.             }
    28.  
    29.             public void TestFinished(ITestResultAdaptor result) { }
    30.             public void TestStarted(ITestAdaptor test) { }
    31.         }
    32.     }
    If I then have a play mode test with a Debug.Log call in it, that call does end up in the console, but the ones from TestCallbacks don't.
     
  2. Warnecke

    Warnecke

    Unity Technologies

    Joined:
    Nov 28, 2017
    Posts:
    92
    Hey. When the editor enters playmode, right before executing the play mode tests, then a domain reload happens. It is necessary for you to re-register your callback after each domain reload. You could use InitializeOnLoad (https://docs.unity3d.com/ScriptReference/InitializeOnLoadAttribute.html) to let trigger a setup method, in which you registers your callback.
     
  3. Martin_KageNova

    Martin_KageNova

    Joined:
    Jul 30, 2019
    Posts:
    7
    Thank you, that did the trick! Is there any way to run both edit mode and play mode tests with a single call to TestRunnerApi.Execute?
     
  4. Warnecke

    Warnecke

    Unity Technologies

    Joined:
    Nov 28, 2017
    Posts:
    92
    Currently not, but that is something we are working on adding.
     
    Martin_KageNova likes this.
  5. pixel_maniacs

    pixel_maniacs

    Joined:
    Jun 25, 2015
    Posts:
    71
    Could you please share your way of implementing it?
     
  6. Warnecke

    Warnecke

    Unity Technologies

    Joined:
    Nov 28, 2017
    Posts:
    92
    What we are doing in a nutshell is just running first EditMode and then PlayMode afterwards, then stitching the results together before reporting them back through the TestRunnerApi.
     
    will_unity731 likes this.
  7. Max_Aigner

    Max_Aigner

    Joined:
    May 9, 2017
    Posts:
    42
    Is there any update on that?

    I have created a bigger Build script that does Unittests as a buildelement. I wanted to run both Playmode and Editmode tests. But when the Playmode-Tests start they also reset the whole buildscript when entering playmode. I tried to store some states in static variables but that does not work. How could I run playmodeTests as part of an automated script?..
     
    shuber_intence likes this.
  8. Rafal_Marchewka

    Rafal_Marchewka

    Joined:
    Apr 1, 2021
    Posts:
    5
    It was whole year ago but I'm leaving my code for posterity:


    using UnityEditor;
    using UnityEditor.TestTools.TestRunner.Api;
    using UnityEngine;

    [InitializeOnLoad]
    public static class TestRunner
    {
    private static TestRunnerApi _runner = null;

    static TestRunner()
    {
    _runner = ScriptableObject.CreateInstance<TestRunnerApi> ();
    _runner.RegisterCallbacks (new MyCallbacks ());
    }

    [MenuItem ("Test/Playmode")]
    public static void RunPlaymodeTests ()
    {
    _runner = ScriptableObject.CreateInstance<TestRunnerApi> ();
    Filter filter = new Filter ()
    {
    testMode = TestMode.PlayMode
    };
    _runner.RegisterCallbacks (new MyCallbacks ());
    _runner.Execute (new ExecutionSettings (filter));
    }


    CreateInstance called multiple times looks weird but it's works somehow. Also, I don't know how it's works together with Editmode tests, because I'm using separate CICD jobs for Playmode, Editmode and for each build.