Unit testing for per-platform initialization code in Unity
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
I have a game that I ported to Android from Windows using Unity 2017.3. This game works with different hardware sensors, and I added functionality to change which sensor is used based on the current platform (at compile time, for now).
Is it appropriate to use unit tests for the GetSensorToInitialize
method below that chooses the sensor for each platform? (This method is used by a MonoBehaviour
to create the sensor instance by calling GameObject.AddComponent
with the appropriate type.)
public class SensorPerPlatform
public const SensorHardware SensorOnWindows = SensorHardware.DeviceA;
public const SensorHardware SensorOnAndroid = SensorHardware.DeviceB;
public const SensorHardware SensorOnEditorWithAndroidBuildTarget = SensorHardware.DeviceC;
private readonly IApplicationHelper _application;
public SensorPerPlatform(IApplicationHelper application)
_application = application;
public SensorHardware GetSensorToInitialize()
if (_application.IsEditorWithAndroidBuildTarget)
return SensorOnEditorWithAndroidBuildTarget;
if (_application.IsWindows)
return SensorOnWindows;
if (_application.IsAndroid)
return SensorOnAndroid;
Debug.LogError("No appropriate sensor, using default");
return SensorHardware.DeviceA;
// Note: not actually named A, B, C. I didn't want to list the actual sensor names here.
public enum SensorHardware
A,
B,
C
Note that ApplicationHelper
is a custom wrapper around UnityEngine.Application that implements the IApplicationHelper
interface to make it possible to create stubs for testing:
public interface IApplicationHelper
bool IsAndroid get;
bool IsWindows get;
bool IsEditorWithAndroidBuildTarget get;
/// <summary>
/// Helper class to add functionality on top of UnityEngine.Application
/// </summary>
/// <remarks>
/// Provide static properties for convenience, as UnityEngine.Application is also used with this paradigm
/// </remarks>
public class ApplicationHelper : IApplicationHelper
public static bool IsAndroid get return Application.platform == RuntimePlatform.Android;
public static bool IsWindows
get
bool isWindowsPlayer = Application.platform == RuntimePlatform.WindowsPlayer;
bool isWindowsEditor = Application.platform == RuntimePlatform.WindowsEditor;
return isWindowsPlayer
public static bool IsInEditorWithAndroidBuildTarget
get
#if UNITY_EDITOR
if (Application.isEditor) return EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android;
#endif
return false;
public static bool IsAndroidPlatformOrBuildTarget get IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsEditorWithAndroidBuildTarget get return IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsWindows get return IsWindows;
bool IApplicationHelper.IsAndroid get return IsAndroid;
Here is my unit testing code that runs the test TestGetSensorToInitialize
with the relevant parameters for Android
, WindowsPlayer
, and WindowsEditor
platforms:
using NSubstitute;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
[...]
[TestFixture]
public class SensorPerPlatformTests
[TestCase(RuntimePlatform.Android, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnAndroid)]
[TestCase(RuntimePlatform.WindowsPlayer, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.StandaloneWindows, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.Android, ExpectedResult = SensorPerPlatform.SensorOnEditorWithAndroidBuildTarget)]
public SensorHardware TestGetSensorToInitialize(RuntimePlatform platform, BuildTarget buildTarget)
var application = GetSubstitute(platform, buildTarget);
var sensorPerPlatform = new SensorPerPlatform(application);
return sensorPerPlatform.GetSensorToInitialize();
private IApplicationHelper GetSubstitute(RuntimePlatform platform, BuildTarget target)
var application = Substitute.For<IApplicationHelper>();
switch (platform)
case RuntimePlatform.Android:
application.IsAndroid.Returns(true);
application.IsWindows.Returns(false);
break;
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
application.IsAndroid.Returns(false);
application.IsWindows.Returns(true);
break;
default:
throw new ArgumentOutOfRangeException();
switch (target)
case BuildTarget.Android:
application.IsEditorWithAndroidBuildTarget.Returns(true);
break;
case BuildTarget.NoTarget:
case BuildTarget.StandaloneWindows:
application.IsEditorWithAndroidBuildTarget.Returns(false);
break;
default:
throw new ArgumentOutOfRangeException();
return application;
The GetSensorToIntialize
method ended up being fairly straightforward, but it took a few iterations to simplify the logic to this. Also, I feel unit testing has helped me to improve the structure of my code, e.g. by better adhering to single responsibility principle.
However, I have some doubts that these tests are overkill for a method whose logic was changed in the end to simply say "If in Unity editor, initialize sensor C. If on Windows, initialize sensor A. If on Android, initialize sensor B."
Am I using unit tests correctly here? I'm seeking feedback related to unit testing, but feedback on any aspect of the code is appreciated as well.
(For some more context, this game is on a legacy code base that doesn't have many unit tests. I've been attempting to slowly add more unit tests during development, but it's been a challenge in part because I feel I do not have enough experience with unit testing in Unity.)
c# unit-testing unity3d
add a comment |Â
up vote
3
down vote
favorite
I have a game that I ported to Android from Windows using Unity 2017.3. This game works with different hardware sensors, and I added functionality to change which sensor is used based on the current platform (at compile time, for now).
Is it appropriate to use unit tests for the GetSensorToInitialize
method below that chooses the sensor for each platform? (This method is used by a MonoBehaviour
to create the sensor instance by calling GameObject.AddComponent
with the appropriate type.)
public class SensorPerPlatform
public const SensorHardware SensorOnWindows = SensorHardware.DeviceA;
public const SensorHardware SensorOnAndroid = SensorHardware.DeviceB;
public const SensorHardware SensorOnEditorWithAndroidBuildTarget = SensorHardware.DeviceC;
private readonly IApplicationHelper _application;
public SensorPerPlatform(IApplicationHelper application)
_application = application;
public SensorHardware GetSensorToInitialize()
if (_application.IsEditorWithAndroidBuildTarget)
return SensorOnEditorWithAndroidBuildTarget;
if (_application.IsWindows)
return SensorOnWindows;
if (_application.IsAndroid)
return SensorOnAndroid;
Debug.LogError("No appropriate sensor, using default");
return SensorHardware.DeviceA;
// Note: not actually named A, B, C. I didn't want to list the actual sensor names here.
public enum SensorHardware
A,
B,
C
Note that ApplicationHelper
is a custom wrapper around UnityEngine.Application that implements the IApplicationHelper
interface to make it possible to create stubs for testing:
public interface IApplicationHelper
bool IsAndroid get;
bool IsWindows get;
bool IsEditorWithAndroidBuildTarget get;
/// <summary>
/// Helper class to add functionality on top of UnityEngine.Application
/// </summary>
/// <remarks>
/// Provide static properties for convenience, as UnityEngine.Application is also used with this paradigm
/// </remarks>
public class ApplicationHelper : IApplicationHelper
public static bool IsAndroid get return Application.platform == RuntimePlatform.Android;
public static bool IsWindows
get
bool isWindowsPlayer = Application.platform == RuntimePlatform.WindowsPlayer;
bool isWindowsEditor = Application.platform == RuntimePlatform.WindowsEditor;
return isWindowsPlayer
public static bool IsInEditorWithAndroidBuildTarget
get
#if UNITY_EDITOR
if (Application.isEditor) return EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android;
#endif
return false;
public static bool IsAndroidPlatformOrBuildTarget get IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsEditorWithAndroidBuildTarget get return IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsWindows get return IsWindows;
bool IApplicationHelper.IsAndroid get return IsAndroid;
Here is my unit testing code that runs the test TestGetSensorToInitialize
with the relevant parameters for Android
, WindowsPlayer
, and WindowsEditor
platforms:
using NSubstitute;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
[...]
[TestFixture]
public class SensorPerPlatformTests
[TestCase(RuntimePlatform.Android, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnAndroid)]
[TestCase(RuntimePlatform.WindowsPlayer, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.StandaloneWindows, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.Android, ExpectedResult = SensorPerPlatform.SensorOnEditorWithAndroidBuildTarget)]
public SensorHardware TestGetSensorToInitialize(RuntimePlatform platform, BuildTarget buildTarget)
var application = GetSubstitute(platform, buildTarget);
var sensorPerPlatform = new SensorPerPlatform(application);
return sensorPerPlatform.GetSensorToInitialize();
private IApplicationHelper GetSubstitute(RuntimePlatform platform, BuildTarget target)
var application = Substitute.For<IApplicationHelper>();
switch (platform)
case RuntimePlatform.Android:
application.IsAndroid.Returns(true);
application.IsWindows.Returns(false);
break;
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
application.IsAndroid.Returns(false);
application.IsWindows.Returns(true);
break;
default:
throw new ArgumentOutOfRangeException();
switch (target)
case BuildTarget.Android:
application.IsEditorWithAndroidBuildTarget.Returns(true);
break;
case BuildTarget.NoTarget:
case BuildTarget.StandaloneWindows:
application.IsEditorWithAndroidBuildTarget.Returns(false);
break;
default:
throw new ArgumentOutOfRangeException();
return application;
The GetSensorToIntialize
method ended up being fairly straightforward, but it took a few iterations to simplify the logic to this. Also, I feel unit testing has helped me to improve the structure of my code, e.g. by better adhering to single responsibility principle.
However, I have some doubts that these tests are overkill for a method whose logic was changed in the end to simply say "If in Unity editor, initialize sensor C. If on Windows, initialize sensor A. If on Android, initialize sensor B."
Am I using unit tests correctly here? I'm seeking feedback related to unit testing, but feedback on any aspect of the code is appreciated as well.
(For some more context, this game is on a legacy code base that doesn't have many unit tests. I've been attempting to slowly add more unit tests during development, but it's been a challenge in part because I feel I do not have enough experience with unit testing in Unity.)
c# unit-testing unity3d
1
Welcome to Code Review! I hope you get some great answers.
â Phrancis
May 1 at 20:20
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I have a game that I ported to Android from Windows using Unity 2017.3. This game works with different hardware sensors, and I added functionality to change which sensor is used based on the current platform (at compile time, for now).
Is it appropriate to use unit tests for the GetSensorToInitialize
method below that chooses the sensor for each platform? (This method is used by a MonoBehaviour
to create the sensor instance by calling GameObject.AddComponent
with the appropriate type.)
public class SensorPerPlatform
public const SensorHardware SensorOnWindows = SensorHardware.DeviceA;
public const SensorHardware SensorOnAndroid = SensorHardware.DeviceB;
public const SensorHardware SensorOnEditorWithAndroidBuildTarget = SensorHardware.DeviceC;
private readonly IApplicationHelper _application;
public SensorPerPlatform(IApplicationHelper application)
_application = application;
public SensorHardware GetSensorToInitialize()
if (_application.IsEditorWithAndroidBuildTarget)
return SensorOnEditorWithAndroidBuildTarget;
if (_application.IsWindows)
return SensorOnWindows;
if (_application.IsAndroid)
return SensorOnAndroid;
Debug.LogError("No appropriate sensor, using default");
return SensorHardware.DeviceA;
// Note: not actually named A, B, C. I didn't want to list the actual sensor names here.
public enum SensorHardware
A,
B,
C
Note that ApplicationHelper
is a custom wrapper around UnityEngine.Application that implements the IApplicationHelper
interface to make it possible to create stubs for testing:
public interface IApplicationHelper
bool IsAndroid get;
bool IsWindows get;
bool IsEditorWithAndroidBuildTarget get;
/// <summary>
/// Helper class to add functionality on top of UnityEngine.Application
/// </summary>
/// <remarks>
/// Provide static properties for convenience, as UnityEngine.Application is also used with this paradigm
/// </remarks>
public class ApplicationHelper : IApplicationHelper
public static bool IsAndroid get return Application.platform == RuntimePlatform.Android;
public static bool IsWindows
get
bool isWindowsPlayer = Application.platform == RuntimePlatform.WindowsPlayer;
bool isWindowsEditor = Application.platform == RuntimePlatform.WindowsEditor;
return isWindowsPlayer
public static bool IsInEditorWithAndroidBuildTarget
get
#if UNITY_EDITOR
if (Application.isEditor) return EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android;
#endif
return false;
public static bool IsAndroidPlatformOrBuildTarget get IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsEditorWithAndroidBuildTarget get return IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsWindows get return IsWindows;
bool IApplicationHelper.IsAndroid get return IsAndroid;
Here is my unit testing code that runs the test TestGetSensorToInitialize
with the relevant parameters for Android
, WindowsPlayer
, and WindowsEditor
platforms:
using NSubstitute;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
[...]
[TestFixture]
public class SensorPerPlatformTests
[TestCase(RuntimePlatform.Android, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnAndroid)]
[TestCase(RuntimePlatform.WindowsPlayer, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.StandaloneWindows, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.Android, ExpectedResult = SensorPerPlatform.SensorOnEditorWithAndroidBuildTarget)]
public SensorHardware TestGetSensorToInitialize(RuntimePlatform platform, BuildTarget buildTarget)
var application = GetSubstitute(platform, buildTarget);
var sensorPerPlatform = new SensorPerPlatform(application);
return sensorPerPlatform.GetSensorToInitialize();
private IApplicationHelper GetSubstitute(RuntimePlatform platform, BuildTarget target)
var application = Substitute.For<IApplicationHelper>();
switch (platform)
case RuntimePlatform.Android:
application.IsAndroid.Returns(true);
application.IsWindows.Returns(false);
break;
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
application.IsAndroid.Returns(false);
application.IsWindows.Returns(true);
break;
default:
throw new ArgumentOutOfRangeException();
switch (target)
case BuildTarget.Android:
application.IsEditorWithAndroidBuildTarget.Returns(true);
break;
case BuildTarget.NoTarget:
case BuildTarget.StandaloneWindows:
application.IsEditorWithAndroidBuildTarget.Returns(false);
break;
default:
throw new ArgumentOutOfRangeException();
return application;
The GetSensorToIntialize
method ended up being fairly straightforward, but it took a few iterations to simplify the logic to this. Also, I feel unit testing has helped me to improve the structure of my code, e.g. by better adhering to single responsibility principle.
However, I have some doubts that these tests are overkill for a method whose logic was changed in the end to simply say "If in Unity editor, initialize sensor C. If on Windows, initialize sensor A. If on Android, initialize sensor B."
Am I using unit tests correctly here? I'm seeking feedback related to unit testing, but feedback on any aspect of the code is appreciated as well.
(For some more context, this game is on a legacy code base that doesn't have many unit tests. I've been attempting to slowly add more unit tests during development, but it's been a challenge in part because I feel I do not have enough experience with unit testing in Unity.)
c# unit-testing unity3d
I have a game that I ported to Android from Windows using Unity 2017.3. This game works with different hardware sensors, and I added functionality to change which sensor is used based on the current platform (at compile time, for now).
Is it appropriate to use unit tests for the GetSensorToInitialize
method below that chooses the sensor for each platform? (This method is used by a MonoBehaviour
to create the sensor instance by calling GameObject.AddComponent
with the appropriate type.)
public class SensorPerPlatform
public const SensorHardware SensorOnWindows = SensorHardware.DeviceA;
public const SensorHardware SensorOnAndroid = SensorHardware.DeviceB;
public const SensorHardware SensorOnEditorWithAndroidBuildTarget = SensorHardware.DeviceC;
private readonly IApplicationHelper _application;
public SensorPerPlatform(IApplicationHelper application)
_application = application;
public SensorHardware GetSensorToInitialize()
if (_application.IsEditorWithAndroidBuildTarget)
return SensorOnEditorWithAndroidBuildTarget;
if (_application.IsWindows)
return SensorOnWindows;
if (_application.IsAndroid)
return SensorOnAndroid;
Debug.LogError("No appropriate sensor, using default");
return SensorHardware.DeviceA;
// Note: not actually named A, B, C. I didn't want to list the actual sensor names here.
public enum SensorHardware
A,
B,
C
Note that ApplicationHelper
is a custom wrapper around UnityEngine.Application that implements the IApplicationHelper
interface to make it possible to create stubs for testing:
public interface IApplicationHelper
bool IsAndroid get;
bool IsWindows get;
bool IsEditorWithAndroidBuildTarget get;
/// <summary>
/// Helper class to add functionality on top of UnityEngine.Application
/// </summary>
/// <remarks>
/// Provide static properties for convenience, as UnityEngine.Application is also used with this paradigm
/// </remarks>
public class ApplicationHelper : IApplicationHelper
public static bool IsAndroid get return Application.platform == RuntimePlatform.Android;
public static bool IsWindows
get
bool isWindowsPlayer = Application.platform == RuntimePlatform.WindowsPlayer;
bool isWindowsEditor = Application.platform == RuntimePlatform.WindowsEditor;
return isWindowsPlayer
public static bool IsInEditorWithAndroidBuildTarget
get
#if UNITY_EDITOR
if (Application.isEditor) return EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android;
#endif
return false;
public static bool IsAndroidPlatformOrBuildTarget get IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsEditorWithAndroidBuildTarget get return IsInEditorWithAndroidBuildTarget;
bool IApplicationHelper.IsWindows get return IsWindows;
bool IApplicationHelper.IsAndroid get return IsAndroid;
Here is my unit testing code that runs the test TestGetSensorToInitialize
with the relevant parameters for Android
, WindowsPlayer
, and WindowsEditor
platforms:
using NSubstitute;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
[...]
[TestFixture]
public class SensorPerPlatformTests
[TestCase(RuntimePlatform.Android, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnAndroid)]
[TestCase(RuntimePlatform.WindowsPlayer, BuildTarget.NoTarget, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.StandaloneWindows, ExpectedResult = SensorPerPlatform.SensorOnWindows)]
[TestCase(RuntimePlatform.WindowsEditor, BuildTarget.Android, ExpectedResult = SensorPerPlatform.SensorOnEditorWithAndroidBuildTarget)]
public SensorHardware TestGetSensorToInitialize(RuntimePlatform platform, BuildTarget buildTarget)
var application = GetSubstitute(platform, buildTarget);
var sensorPerPlatform = new SensorPerPlatform(application);
return sensorPerPlatform.GetSensorToInitialize();
private IApplicationHelper GetSubstitute(RuntimePlatform platform, BuildTarget target)
var application = Substitute.For<IApplicationHelper>();
switch (platform)
case RuntimePlatform.Android:
application.IsAndroid.Returns(true);
application.IsWindows.Returns(false);
break;
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
application.IsAndroid.Returns(false);
application.IsWindows.Returns(true);
break;
default:
throw new ArgumentOutOfRangeException();
switch (target)
case BuildTarget.Android:
application.IsEditorWithAndroidBuildTarget.Returns(true);
break;
case BuildTarget.NoTarget:
case BuildTarget.StandaloneWindows:
application.IsEditorWithAndroidBuildTarget.Returns(false);
break;
default:
throw new ArgumentOutOfRangeException();
return application;
The GetSensorToIntialize
method ended up being fairly straightforward, but it took a few iterations to simplify the logic to this. Also, I feel unit testing has helped me to improve the structure of my code, e.g. by better adhering to single responsibility principle.
However, I have some doubts that these tests are overkill for a method whose logic was changed in the end to simply say "If in Unity editor, initialize sensor C. If on Windows, initialize sensor A. If on Android, initialize sensor B."
Am I using unit tests correctly here? I'm seeking feedback related to unit testing, but feedback on any aspect of the code is appreciated as well.
(For some more context, this game is on a legacy code base that doesn't have many unit tests. I've been attempting to slowly add more unit tests during development, but it's been a challenge in part because I feel I do not have enough experience with unit testing in Unity.)
c# unit-testing unity3d
asked May 1 at 19:04
sonny
1819
1819
1
Welcome to Code Review! I hope you get some great answers.
â Phrancis
May 1 at 20:20
add a comment |Â
1
Welcome to Code Review! I hope you get some great answers.
â Phrancis
May 1 at 20:20
1
1
Welcome to Code Review! I hope you get some great answers.
â Phrancis
May 1 at 20:20
Welcome to Code Review! I hope you get some great answers.
â Phrancis
May 1 at 20:20
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193380%2funit-testing-for-per-platform-initialization-code-in-unity%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Welcome to Code Review! I hope you get some great answers.
â Phrancis
May 1 at 20:20