Setting up Low Level Tests for an EditorSubsystem in an Editor Mode Plugin

Hi all.

I’m working on an plugin based on the Editor Mode example, and I’ve added a subsystem that inherits from UEditorSubsystem.

I’d like to add some automated tests for this subsystem, and I’d like to implement them as Low Level Tests.

My subsystem is located as follows:

  • Header file: Plugins/DungeonBuilder/Source/DungeonBuilder/Public/Subsystems/DungeonConfigSubsystem.h
  • CPP file: Plugins/DungeonBuilder/Source/DungeonBuilder/Private/Subsystems/DungeonConfigSubsystem.cpp

I’ve added the following folders/files in order to setup the Low Level Tests:

  • Plugins/DungeonBuilder/Tests/DungeonBuilderTests/ which contains 2 files:
    • DungeonBuilderTests.Build.cs
    • DungeonBuilderTests.Target.cs
  • Plugins/DungeonBuilder/Tests/DungeonBuilderTests/Private/Subsystems, which contains a test file:
    • DungeonConfigSubsystemTests.cpp

The test is very simple:

include “CoreMinimal.h”
include “Subsystems/DungeonConfigSubsystem.h”
include “TestHarness.h”

SCENARIO(“DungeonConfigHelper Unit Tests”, “[DungeonConfigHelper]”)
{
GIVEN(“A test”)
{
WHEN(“something happens”)
{
THEN(“it succeeds”)
{
REQUIRE(true);
}
}
}
}

DungeonBuilderTests.Build.cs contains:

using UnrealBuildTool;

public class DungeonBuilderTests : TestModuleRules
{
static DungeonBuilderTests()
{
if (InTestMode)
{
TestMetadata = new Metadata();
TestMetadata.TestName = “DungeonBuilder”;
TestMetadata.TestShortName = “Dungeon Builder”;
TestMetadata.UsesCatch2 = true;
TestMetadata.SupportedPlatforms.Clear();
TestMetadata.SupportedPlatforms.Add(UnrealTargetPlatform.Win64);
}
}

public DungeonBuilderTests(ReadOnlyTargetRules Target) : base(Target)
{
    OptimizeCode = CodeOptimization.Never;

    PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
    PrivateDependencyModuleNames.AddRange(
        new string[] {
            "Core",
            "UnrealEd"
        });

    PublicDependencyModuleNames.AddRange(
        new string[] {
            "DungeonBuilder"
        });
}

}

And DungeonBuilderTests.Target.cs contains:

using UnrealBuildTool;

public class DungeonBuilderTestsTarget : TestTargetRules
{
public DungeonBuilderTestsTarget(TargetInfo Target) : base(Target)
{
bForceEnableExceptions = true;

    bUsePlatformFileStub = true;
    bMockEngineDefaults = true;

    bBuildWithEditorOnlyData = true;
    bCompileAgainstEditor = true;
}

}

If I don’t include my subsystem’s header in the test file, I can remove the dependencies to my Plugin’s module, as well as UnrealEd’s dependency, and the test project builds correctly and the test runs in Visual Studio.
Including my subsystem causes a build failure in the Test project. By adding dependencies to UnrealEd, my module, and setting the variables in the Target.cs file as shown, it “mostly” builds, but it still fails.

Examples of the build outputs are:

2>[1/8] Compile [x64] EditorUtilities.cpp 12>G:\UnrealEngine\Engine\Source\Developer\LowLevelTestsRunner\Private\TestCommon\EditorUtilities.cpp(18): error C2061: syntax error: identifier 'FQueuedLowLevelThreadPool' 12>G:\UnrealEngine\Engine\Source\Developer\LowLevelTestsRunner\Private\TestCommon\EditorUtilities.cpp(21): error C2061: syntax error: identifier 'FQueuedThreadPoolWrapper' ... [2/8] Compile [x64] Initialization.cpp 12>G:\UnrealEngine\Engine\Source\Developer\LowLevelTestsRunner\Private\TestCommon\Initialization.cpp(22): error C3861: 'InitEditorThreadPools': identifier not found 12>G:\UnrealEngine\Engine\Source\Developer\LowLevelTestsRunner\Private\TestCommon\Initialization.cpp(121): error C3861: 'InitDerivedDataCache': identifier not found ... [3/8] Compile [x64] Module.DeviceProfileServices.cpp 12>G:\UnrealEngine\Engine\Source\Editor\DeviceProfileServices\Private\CheckAndroidDeviceProfileCommandlet.cpp(172): error C2039: 'SetPreviewMemorySizeBucket': is not a member of 'UDeviceProfile' 12>G:\UnrealEngine\Engine\Source\Runtime\Engine\Public\IDeviceProfileSelectorModule.h(13): note: see declaration of 'UDeviceProfile' ... [4/8] Compile [x64] Module.Landscape.3.cpp 12>G:\UnrealEngine\Engine\Source\Runtime\Landscape\Private\Landscape.cpp(760): error C2039: 'GetPlatformValueVariable': is not a member of 'IConsoleVariable' ... 12>[5/8] Compile [x64] Module.UnrealEd.25.cpp 12>G:\UnrealEngine\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp(6354): error C2039: 'RestorePreviewDeviceProfile': is not a member of 'UDeviceProfileManager' ...

I think I am missing a module dependency or some config variable that I’m not aware of. Does anybody know what I could be missing?
Should I change the folder structure for my tests? Should I extract the tests to a different plugin?
Or is it that Low Level Tests are not meant to be used with Editor related classes?

Thanks in advance.

1 Like

As a follow up, I’ve not been able to solve this issue, so I’ve implemented my tests as specs instead.

However, if anyone can figure this out, please let me know. Thanks!

This looks wrong to me - id imagine it should instead path like this.

Plugins/DungeonBuilder/Source/Public/Subsystems/DungeonConfigSubsystem.h