|
Kanda Foundation 0.2.0
|
The Kanda SDK includes a comprehensive testing framework designed to facilitate automated testing within Unity. This framework supports a variety of testing paradigms to ensure high code coverage and robust functionality. Utilizing the Unity Test Runner, developers are encouraged to achieve over 80% test coverage, even though this is not a strict requirement.
The Kanda Foundation Tests Framework, provided under the Kanda.Foundation.Tests namespace, includes a batteries-included setup for testing. This framework offers basic scaffolds and templates that can be used to quickly set up test classes. Additionally, several base classes and test helpers are provided to streamline the testing process.
IAppLifecycleService to isolate components under test.These are preferred over play mode tests due to their faster execution and higher stability. Play mode tests, while useful for high-level integration testing, tend to be slow and brittle, especially across different platforms.
Units, in this context, should be understood as behaviours of MonoBehaviours, systems, or services.
This does not necessarily mean test every public method of every class. Instead, focusing on the high-level behaviors of a component under different circumstances will usually provide the required coverage on low-level methods.
In our experience, unit-component tests offer the best balance between development time, coverage, and test robustness.
In Unity, many functions produce side effects rather than return values. Test will typically focus on these side effects resulting from component behaviours by checking outcomes in states or downstream actions.
A well-structured test often follows this template:
To help future readers, annotate your tests using If-When-Then comments as demonstrated in later sections. This is a variant on the Arrange-Act-Assert pattern where the If-When-Then convention helps encourage natural and easy-to-read language.
State Verification: Set up initial state, perform an action, then verify the resulting world state.
Action Verification: Use mocks to verify that certain actions trigger expected downstream behaviors. This is sometimes necessary when the side-effect produced is not a return value, or data artifact, but an action triggered in the Unity engine.
Use interfaces and object wrappers to abstract Unity APIs that are difficult to mock, such as static classes. This allows for more flexible and testable code.
In tests, you can now swap out the concrete implementation with a mock.
Custom scripting symbols such as #if UNITY_EDITOR or #if UNITY_SERVER compile code conditionally depending on platform.
This makes it hard to write good edit-mode tests, as testing code compiled for a specific platform typically requires a player to be built for the given platform. It also makes code hard to read and errors or typos for platforms (other than your current one) can be difficult to spot.
Unless the code specifically depends on APIs only available on some platforms, you can use IPlatformInfoService to get runtime information about the current platform.
Services are utility classes that can be accessed across applications or scenes. Instead of using singletons, consider using services to avoid making code hard to test. Use the Service Containers and App Service Locator framework to register and manage services.
Register the service at application startup and access it using the App Service Locator.
During tests, replace these services with mocks or fakes to isolate the code being tested.
The testing framework and guidelines are designed to facilitate efficient and effective automated testing in Unity. By focusing on edit-mode unit tests, behavioral testing, and utilizing abstractions and services, developers can achieve high test coverage and maintain robust, reliable code.