Refactor FlaxTests to run as Editor with all engine services initialized

This commit is contained in:
Wojtek Figat
2022-07-26 23:07:10 +02:00
parent ff1fba403d
commit bbb5b68e91
8 changed files with 94 additions and 26 deletions

View File

@@ -21,11 +21,13 @@
#include "Engine/Engine/Globals.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Streaming/StreamingSettings.h"
#if FLAX_TESTS
#include "Engine/Platform/FileSystem.h"
#endif
class GameSettingsService : public EngineService
{
public:
GameSettingsService()
: EngineService(TEXT("GameSettings"), -70)
{
@@ -49,7 +51,7 @@ IMPLEMENT_ENGINE_SETTINGS_GETTER(StreamingSettings, Streaming);
#if !USE_EDITOR
#if PLATFORM_WINDOWS
IMPLEMENT_ENGINE_SETTINGS_GETTER(WindowsPlatformSettings, WindowsPlatform);
#elif PLATFORM_UWP
#elif PLATFORM_UWP
IMPLEMENT_ENGINE_SETTINGS_GETTER(UWPPlatformSettings, UWPPlatform);
#elif PLATFORM_LINUX
IMPLEMENT_ENGINE_SETTINGS_GETTER(LinuxPlatformSettings, LinuxPlatform);
@@ -83,6 +85,11 @@ GameSettings* GameSettings::Get()
// It may be missing in editor during dev but must be ready in the build game.
PROFILE_CPU();
const auto assetPath = Globals::ProjectContentFolder / TEXT("GameSettings.json");
#if FLAX_TESTS
// Silence missing GameSettings during test run before Editor creates it (not important)
if (!FileSystem::FileExists(assetPath))
return nullptr;
#endif
GameSettingsAsset = Content::LoadAsync<JsonAsset>(assetPath);
if (GameSettingsAsset == nullptr)
{

View File

@@ -84,6 +84,14 @@ int32 Engine::Main(const Char* cmdLine)
return -1;
}
#if FLAX_TESTS
// Configure engine for test running environment
CommandLine::Options.Headless = true;
CommandLine::Options.Null = true;
CommandLine::Options.Mute = true;
CommandLine::Options.Std = true;
#endif
if (Platform::Init())
{
Platform::Fatal(TEXT("Cannot init platform."));
@@ -102,6 +110,11 @@ int32 Engine::Main(const Char* cmdLine)
StringUtils::PathRemoveRelativeParts(Globals::StartupFolder);
FileSystem::NormalizePath(Globals::BinariesFolder);
FileSystem::GetSpecialFolderPath(SpecialFolder::Temporary, Globals::TemporaryFolder);
if (Globals::TemporaryFolder.IsEmpty())
Platform::Fatal(TEXT("Failed to gather temporary folder directory."));
Globals::TemporaryFolder /= Guid::New().ToString(Guid::FormatType::D);
// Load game info or project info
{
const int32 result = Application::LoadProduct();
@@ -512,12 +525,6 @@ void EngineImpl::InitLog()
void EngineImpl::InitPaths()
{
// Prepare temp folder path
FileSystem::GetSpecialFolderPath(SpecialFolder::Temporary, Globals::TemporaryFolder);
if (Globals::TemporaryFolder.IsEmpty())
Platform::Fatal(TEXT("Failed to gather temporary folder directory."));
Globals::TemporaryFolder /= Guid::New().ToString(Guid::FormatType::D);
// Cache other global paths
FileSystem::GetSpecialFolderPath(SpecialFolder::LocalAppData, Globals::ProductLocalFolder);
if (Globals::ProductLocalFolder.IsEmpty())
@@ -551,7 +558,7 @@ void EngineImpl::InitPaths()
if (!Globals::StartupFolder.IsANSI())
Platform::Fatal(TEXT("Cannot start application in directory which name contains non-ANSI characters."));
#if !PLATFORM_SWITCH
#if !PLATFORM_SWITCH && !FLAX_TESTS
// Setup directories
if (FileSystem::DirectoryExists(Globals::TemporaryFolder))
FileSystem::DeleteDirectory(Globals::TemporaryFolder);

View File

@@ -27,8 +27,17 @@ __declspec(dllexport) int32 AmdPowerXpressRequestHighPerformance = 1;
extern LONG CALLBACK SehExceptionHandler(EXCEPTION_POINTERS* ep);
#if FLAX_TESTS
int main(int argc, char* argv[])
#else
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
#endif
{
#if FLAX_TESTS
HINSTANCE hInstance = GetModuleHandle(NULL);
LPTSTR lpCmdLine = GetCommandLineW();
#endif
#ifdef USE_VS_MEM_LEAKS_CHECK
// Memory leaks detect inside VS
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);

View File

@@ -2,13 +2,46 @@
#if PLATFORM_WINDOWS || PLATFORM_LINUX || PLATFORM_MAC
#include "Engine/Core/Log.h"
#include "Engine/Engine/Engine.h"
#include "Engine/Engine/EngineService.h"
#include "Engine/Scripting/Scripting.h"
#include "Editor/Scripting/ScriptsBuilder.h"
#define CATCH_CONFIG_RUNNER
#include <ThirdParty/catch2/catch.hpp>
int main(int argc, char* argv[])
class TestsRunnerService : public EngineService
{
int result = Catch::Session().run(argc, argv);
return result;
public:
TestsRunnerService()
: EngineService(TEXT("TestsRunnerService"), 10000)
{
}
void Update() override;
};
TestsRunnerService TestsRunnerServiceInstance;
void TestsRunnerService::Update()
{
// Wait for Editor to be ready for running tests (eg. scripting loaded)
if (!ScriptsBuilder::IsReady() ||
!Scripting::IsEveryAssemblyLoaded() ||
!Scripting::HasGameModulesLoaded())
return;
// Runs tests
Log::Logger::WriteFloor();
LOG(Info, "Running Flax Tests...");
const int result = Catch::Session().run();
if (result == 0)
LOG(Info, "Result: {0}", result);
else
LOG(Error, "Result: {0}", result);
Log::Logger::WriteFloor();
Engine::RequestExit(result);
}
#endif

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using Flax.Build;
using Flax.Build.NativeCpp;
/// <summary>
/// Engine tests module.
@@ -14,6 +15,15 @@ public class Tests : EngineModule
Deploy = false;
}
/// <inheritdoc />
public override void Setup(BuildOptions options)
{
base.Setup(options);
options.PrivateDependencies.Add("Content");
options.PrivateDependencies.Add("Level");
}
/// <inheritdoc />
public override void GetFilesToDeploy(List<string> files)
{