Search Unity

How to use NUnit's Timeout attribute to stop coroutine

Discussion in 'Scripting' started by mysticfall, Mar 5, 2017.

  1. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    I wrote a simple test case using Unity Test Tools, and I'd like to use NUnit's 'Timeout' attribute to handle timeout declaratively.

    I tried the following code, but it seems that even though timeout itself works correctly (meaning failing the test), it doesn't stop the coroutine which causes the Unity TestRunner to hang indefinitely:

    Code (CSharp):
    1.  
    2.         [UnityTest, Timeout(3), Description("It should move towards the target destination.")]
    3.         public IEnumerator ShouldMoveTowardsTargetDestination(
    4.             [TestRange(0, 360, 45)] float heading,
    5.             [Values(1, 10)] float distance)
    6.         {
    7.             Debug.LogFormat("Using data: heading={0}deg., distance={1}m.", heading, distance);
    8.  
    9.             var transform = Navigator.Transform;
    10.             var destination = Quaternion.AngleAxis(heading, transform.up) * transform.forward * distance;
    11.  
    12.             Navigator.Destination = destination;
    13.  
    14.             while (transform.position != destination)
    15.             {
    16.                 Navigator.LateTick();
    17.  
    18.                 yield return null;
    19.             }
    20.  
    21.             Expect(
    22.                 transform.position,
    23.                 Is.EqualTo(destination),
    24.                 "Navigator has failed to reach the destination.");
    25.         }
    Is there any way to use `Timeout` attribute, rather than programatically checking elapsed time? Or is it possible to exit the while loop once the surrounding test fails?

    Thanks!
     
  2. Cloyz

    Cloyz

    Joined:
    Nov 23, 2017
    Posts:
    1
    @mysticfall Did you found a solution/workaround for that ?
     
  3. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    Sorry, I haven't yet. Maybe we should try it again with the latest version and report an issue if it's still broken.
     
  4. Cephos

    Cephos

    Joined:
    Jun 30, 2017
    Posts:
    1
    Nunit supports its own timeout attribute. However I don't think your syntax is quite right. Try something like this:
    Code (CSharp):
    1. [UnityTest]
    2. [Timeout(int.MaxValue)]
    3. public IEnumerator someName()
    4. {
    5.     yield return null;
    6. }
    Of note is that for some reason there is a default 30 second timeout which if hit will cause the test to pass...So I tend to set it to max and handle any timeouts within the test itself, but your milage may vary. Hope this helps.

    Other random thought....why not just assert your timeout?
    Code (CSharp):
    1. Assert.That(actual, Is.EqualTo(expected).After(5000, 50));
     
    Last edited: Feb 23, 2018