Problems understanding latent functions in Automation Spec

Hello, I am trying write an automation spec to test a component that is checking for hit results from a line trace that runs on tick. I want it to just wait a second for the tick on the component to run so I’m trying to use a LatentBeforeEach, but I don’t seem to understand how to do this properly and all the resources I’ve looked at are just leaving me more confused. This is what I have in my LatentBeforeEach block right now but when I run it, it times out. Could someone help point me in the right direction?

			LatentBeforeEach([this](const FDoneDelegate& Done)
			{
				Actor->SetActorLocation(FVector::ZeroVector);
				const FVector StartLocation = FVector(10, 0, 0);
				Interactable->SetActorLocation(StartLocation);
				FWaitLatentCommand(1);
				Done.Execute();
				
				
			});

I ended up figuring out how to do this after piecing things together from multiple resources.

My first problem was that I was trying to create a world in the test. The problem with this is that it the engine doesn’t seem to run tick for worlds that are not playing.
The solution to this was to create an empty world and load it from the test. This had to be done through the Latent before each. Then after the map is loaded you have to start the PIE for the world to tick.

LatentBeforeEach(EAsyncExecution::TaskGraph, [this](const FDoneDelegate& Done)
{
	AsyncTask(ENamedThreads::GameThread, [this, Done]()
	{
		const FString TestWorldName = TEXT("/Interaction/TestMaps/VoidWorld");
		if (bMapLoaded == false)
		{
			FAutomationEditorCommonUtils::LoadMap(TestWorldName);
			bMapLoaded = true;
		}
		FStartPIECommand(true).Update();
		Done.Execute();
	});
});

The other piece to allow the world to wait for a tick is done using the same Async task method however it needs to be done on AnyThread rather than the game thread or else it will cause the game thread to hang.

AsyncTask(ENamedThreads::AnyThread, [this, Done]()
{
      bool bNextFrameWaited = false;
      while (bNextFrameWaited == false)
      {
   	bNextFrameWaited = FWaitForNextEngineFrameCommand().Update();
      }
      Done.Execute();
}

Also as far as I understand, part of the reason the Done.Execute() needs to be called inside the Task is because it needs to be bound in order for it to fire off properly. There are examples that I found online of binding it to other functions but there always seemed to be so much missing context that I don’t really understand how that 's done properly.

After figuring this out I have a new problem that I’m trying to understand.
When I run the tests in the editor sometimes it crashes before loading the map. The IDE is showing the error:

Assertion failed: !LevelList.Contains(TickTaskLevel)

Before I migrated my project to 5.4 this only happened when it would try to re-open my test map, hence the check to see if the map has already been loaded. Now it does this when any map is open other than my test map. This doesn’t happen using the normal test workflow doing the same thing. I’m guessing a bug might have been introduced into 5.4, but does anyone else have an idea? I may open another post for this if it still occurs in subsequent releases.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.