본문 바로가기
Unity3d

[Unity3D] UnitTest UnityManual 에 있는 걸로 테스트 해보기

by 사랑파워 2021. 5. 12.

 

저번에 만들었던 NewTestScript에 UnityManual에 있는 테스트 가능 한 스크립트를 추가 해 보았다.

using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;

namespace Tests
{
    public class NewTestScript
    {
        // A Test behaves as an ordinary method
        [Test]
        public void NewTestScriptSimplePasses()
        {
            // Use the Assert class to test conditions
        }

        // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
        // `yield return null;` to skip a frame.
        [UnityTest]
        public IEnumerator NewTestScriptWithEnumeratorPasses()
        {
            // Use the Assert class to test conditions.
            // Use yield to skip a frame.
            yield return null;
        }

        [Test]
        public void GameObject_CreatedWithGiven_WillHaveTheName()
        {
            var go = new GameObject("MyGameObject");
            Assert.AreEqual("MyGameObject", go.name);
        }

        [UnityTest]
        public IEnumerator GameObject_WithRigidBody_WillBeAffectedByPhysics() 
        {
            var go = new GameObject();
            go.AddComponent<Rigidbody>();
            var originalPosition = go.transform.position.y;

            yield return new WaitForFixedUpdate();

            Assert.AreNotEqual(originalPosition, go.transform.position.y);
        }

        [Test]
        public void LogAssertExample()
        {
            //Expect a regular log message
            LogAssert.Expect(LogType.Log, "Log message");
            //A log message is expected so without the following line
            //the test would fail
            Debug.Log("Log message");
            //An error log is printed
            Debug.LogError("Error message");
            //Without expecting an error log, the test would fail
            LogAssert.Expect(LogType.Error, "Error message");
        }

        [UnityTest]
        public IEnumerator MonoBehaviourTest_Works()
        {
            yield return new MonoBehaviourTest<MyMonoBehaviourTest>();
        }

        public class MyMonoBehaviourTest : MonoBehaviour, IMonoBehaviourTest
        {
            private int frameCount;
            public bool IsTestFinished
            {
                get { return frameCount > 10; }
            }

            void Update()
            {
                frameCount++;
            }
        }
    }
}

TestRunner 창을 보면 기존에 있던 함수 보다 4개 더 생긴것을 볼 수 있다.

 

1. GameObject_CreatedWithGiven_WillHaveTheName 테스트

      [Test]
        public void GameObject_CreatedWithGiven_WillHaveTheName()
        {
            var go = new GameObject("MyGameObject");
            Assert.AreEqual("MyGameObject", go.name);
        }

 

Assert는 Test를 실행시키는 클래스 인 듯 하며

AreEqual은 AreEqual에 정의한 내용이 동일 한 지 테스트 해주는 함수 인 듯 하다.

 

Test Runner 창에서 Test 하고자 하는 함수를 선택해서 실행 할 수 도 있다.

GaeObject_CreatedWithGiven_WillHaveTheName 를 선택 한 후 Run Selected 버튼을 클릭하면

테스트 결과 정상으로 나타난다.

2. GameObject_WithRigidBody_WillBeAffectedByPhysics 테스트

        [UnityTest]
        public IEnumerator GameObject_WithRigidBody_WillBeAffectedByPhysics() 
        {
            var go = new GameObject();
            go.AddComponent<Rigidbody>();
            var originalPosition = go.transform.position.y;

            yield return new WaitForFixedUpdate();

            Assert.AreNotEqual(originalPosition, go.transform.position.y);
        }

AreNotEqual은 AreEqual과 반대 되는 내용 인 듯 하다.

Test Runner 창에서 GameObject_WithRigidBody_WillBeAffectedByPhysics 선택 한 후 Run Selected 를 클릭한다.

테스트 실패

테스트 실패 에 대한 이유는 로그로 나타난다.

EditMode 에서는 Coroutine 테스트 시 yieldnull 밖에 사용 할 수 없다고 한다

GameObject_WithRigidBody_WillBeAffectedByPhysics 는 다음 번에 PlayMode를 만들어서 테스트 해 봐야 겠다

 

3. LogAssertExample 테스트

        [Test]
        public void LogAssertExample()
        {
            //Expect a regular log message
            LogAssert.Expect(LogType.Log, "Log message");
            //A log message is expected so without the following line
            //the test would fail
            Debug.Log("Log message");
            //An error log is printed
            Debug.LogError("Error message");
            //Without expecting an error log, the test would fail
            LogAssert.Expect(LogType.Error, "Error message");
        }

테스트 시 로그 표시를 해 주는 듯 하다.

LogAssertExample 를 선택하여 실행 시켜 보면 테스트는 성공 이며

Console 창에 Log 가 뜨게 된다.

LogAssert.Expect 는 Log가 뜨는 내용을 예상 하여 작성 하는 듯 하다. 말이 이상 한 듯 하지만

Debug.Log("Log message"); 를 주석 처리 하면 테스트가 실패 하는 것을 볼 수 있다.

4. MonoBehaviourTest_Works 테스트

        [UnityTest]
        public IEnumerator MonoBehaviourTest_Works()
        {
            yield return new MonoBehaviourTest<MyMonoBehaviourTest>();
        }

        public class MyMonoBehaviourTest : MonoBehaviour, IMonoBehaviourTest
        {
            private int frameCount;
            public bool IsTestFinished
            {
                get { return frameCount > 10; }
            }

            void Update()
            {
                frameCount++;
            }
        }

MyMonoBehaviourTest 를 생성 하여 10프레임 이 지나면 Finished true를 리턴 해주는 함수이다.

테스트를 실행 시켜 보면

MonoBehaviourTest_Works (0.047s)
---
System.InvalidOperationException : The following game object is invoking the DontDestroyOnLoad method: MonoBehaviourTest: Tests.NewTestScript+MyMonoBehaviourTest. Notice that DontDestroyOnLoad can only be used in play mode and, as such, cannot be part of an editor script.
---

이러한 이유로 에러가 뜨는데

 

아마 MonoBehaviour에 DonDestroyOnLoad를 호출 하는게 포함 되어있는데 이 부분은 PlayMode 에서만 사용 할 수 있어 EditMode에서는 불가능 하다고 한다.

 

나중에 PlayMode로 UnitTest 하는 경우 위에 실패했던 2가지 경우를 테스트 해 봐야겠다.

댓글