Тесты PlayMode с Coroutine SetUp - PullRequest
       26

Тесты PlayMode с Coroutine SetUp

0 голосов
/ 19 октября 2019

Я новичок в тестировании Unity3D, и я хотел написать несколько тестов для нашей игры. Мне удалось написать эти тесты, которые работают отлично :

using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Game.Characters;
using Game.Inventory;

namespace Tests
{
    public class ItemTests
    {
        [UnityTest]
        public IEnumerator ItemIsOnHand()
        {
            // Setup
            Player player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
            yield return null; // Wait for prefab to load
            Character character = player.GetComponent<Character>();
            WorldItem worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
            yield return null; // Wait for prefab to load
            character.Inventory.Give(worldItem);
            ItemScript itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();

            // Test
            Assert.IsNotNull(itemScript);

            // Teardown
            Object.Destroy(player);
            Object.Destroy(character);
            Object.Destroy(worldItem);
            Object.Destroy(itemScript);
        }

        [UnityTest]
        public IEnumerator ItemIsDisabledAtStart()
        {
            // Setup
            Player player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
            yield return null; // Wait for prefab to load
            Character character = player.GetComponent<Character>();
            WorldItem worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
            yield return null; // Wait for prefab to load
            character.Inventory.Give(worldItem);
            ItemScript itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();

            // Test
            Assert.IsFalse(itemScript.IsActive);

            // Teardown
            Object.Destroy(player);
            Object.Destroy(character);
            Object.Destroy(worldItem);
            Object.Destroy(itemScript); 
        }
    }
}

Как видите, оба теста (и другие тесты тоже) используют одинаковые настройки и демонтаж. Я объявляю переменные вне методов (которые будут доступны для каждого теста). Метод сноса работает нормально, так как ему не нужно ждать, пока что-нибудь загрузится.

        private Player player;
        private Character character;
        private WorldItem worldItem;
        private ItemScript itemScript;

        [TearDown]
        public void Teardown()
        {
            Debug.Log("Teardown called");
            Object.Destroy(player);
            Object.Destroy(character);
            Object.Destroy(ectomodulatorWorldItem);
        }

Но мне не удается заставить метод SetUp работать. Если я сделаю это сопрограммой ([SetUp] public IEnumerator SetUp(){...}), она никогда не запустится (я проверил с помощью отладчика). И если я сделаю его простым методом void и удаляю yield return null s, он завершится с ошибкой character.Inventory.Give(worldItem);, потому что worldItem все еще null.

Есть ли способ заставить метод SetUp работать?

Спасибо

1 Ответ

0 голосов
/ 22 октября 2019

Я нашел то, что мне было нужно. Так же, как атрибут [Test] работает только на void методах, и вам нужно использовать [UnityTest] для запуска сопрограммы, есть также атрибут [UnitySetUp], который позволяет использовать установку сопрограммы вместо void.

Ссылка на документы для получения дополнительной информации: https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/reference-actions-outside-tests.html#unitysetup-and-unityteardown

Если вам интересно, мой файл тестов выглядит так:

using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Game.Characters;
using Game.Inventory;

namespace Tests
{
    public class ItemTests
    {
        Player player;
        Character character;
        WorldItem worldItem;
        ItemScript itemScript;

        [UnitySetUp]
        public IEnumerator SetUp()
        {
            player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
            yield return null; // Wait for prefab to load
            character = player.GetComponent<Character>();
            worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
            yield return null; // Wait for prefab to load
            character.Inventory.Give(worldItem);
            itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();
        }

        [TearDown]
        public void Teardown()
        {
            Object.Destroy(player);
            Object.Destroy(character);
            Object.Destroy(ectomodulatorWorldItem);
        }

        [Test]
        public void ItemIsOnHand()
        {
            // Test
            Assert.IsNotNull(itemScript);
        }

        [Test]
        public void ItemIsDisabledAtStart()
        {
            // Test
            Assert.IsFalse(itemScript.IsActive);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...