##I solved it!!
I could finally do something to test this, it’s a caveman solution but it works and I know it could be refactored into something better.
So, the problem was that addAcceleration required AddForce to move the actor (which is applied on the next tick) and I was trying to test it in the same frame that it was called (which always made the test fail). I tried to use timers but I couldn’t make them work. I thought of using tick functions but I didn’t understand how to make my own very well.
Then I had an idea: latent commands are called every frame until they return true, so, what if I use one of them as a tick counter and check if there’s a change as a condition to then run the test.
Now I thought that yes, that could work if I know that sometime in the future I would be receiving a change. What if that change never came? Well, this is the caveman workaround: I count every time the latent command is called and I use a limit to stop calling it if the actor location didn’t change after a few frames. If that happens, the test fails and an error is displayed, telling that the tick limit was reached.
The above refers to this piece of code:
DEFINE_LATENT_AUTOMATION_COMMAND_THREE_PARAMETER(FCheckAJetLocationCommand, int*, tickCount, int*, tickLimit, FAutomationTestBase*, test);
bool FCheckAJetLocationCommand::Update()
{
if (GEditor->IsPlayingSessionInEditor())
{
UWorld* testWorld = GEditor->GetPIEWorldContext()->World();
AJet* testJet = Cast<AJet, AActor>(UGameplayStatics::GetActorOfClass(testWorld, AJet::StaticClass()));
if (testJet)
{
FVector currentLocation = testJet->GetActorLocation();
if (currentLocation.X > 0)//it would be better to align the ship first and then check against it's forward vector. Be have to be careful of gravity in this test.
{
check(test);
test->TestTrue(TEXT("The Jet X location should increase after an acceleration is added (after ticking)."), currentLocation.X > 0);
return true;
}
else
{
*tickCount = *tickCount + 1;
if ( (*tickCount) > (*tickLimit))
{
test->TestFalse(TEXT("Tick limit reached for this test. The Jet Location never changed from (0,0,0)."), *tickCount > *tickLimit);
return true;
}
}
}
}
return false;
}
The full test is as follows:
#include "JetTest.h"
#include "Jet.h"
#include "Misc/AutomationTest.h"
#include "Tests/AutomationEditorCommon.h"
#include "Editor.h"
#include "Kismet/GameplayStatics.h"
#if WITH_DEV_AUTOMATION_TESTS
DEFINE_LATENT_AUTOMATION_COMMAND_ONE_PARAMETER(FSpawningAJetMakeItAccelerateCommand, FAutomationTestBase*, test);
bool FSpawningAJetMakeItAccelerateCommand::Update()
{
if (!GEditor->IsPlayingSessionInEditor())//if not, everything would be made while the map is loading and the PIE is in progress.
{
return false;
}
UWorld* testWorld = GEditor->GetPIEWorldContext()->World();
AJet* testJet = testWorld->SpawnActor<AJet>(AJet::StaticClass());
FVector forceToApply = FVector(10000);
testJet->addAcceleration(forceToApply);
return true;
}
DEFINE_LATENT_AUTOMATION_COMMAND_THREE_PARAMETER(FCheckAJetLocationCommand, int*, tickCount, int*, tickLimit, FAutomationTestBase*, test);
bool FCheckAJetLocationCommand::Update()
{
if (GEditor->IsPlayingSessionInEditor())
{
UWorld* testWorld = GEditor->GetPIEWorldContext()->World();
AJet* testJet = Cast<AJet, AActor>(UGameplayStatics::GetActorOfClass(testWorld, AJet::StaticClass()));
if (testJet)
{
FVector currentLocation = testJet->GetActorLocation();
if (currentLocation.X > 0)//it would be better to align the ship first and then check against it's forward vector. Be have to be careful of gravity in this test.
{
check(test);
test->TestTrue(TEXT("The Jet X location should increase after an acceleration is added (after ticking)."), currentLocation.X > 0);
return true;
}
else
{
*tickCount = *tickCount + 1;
if ( (*tickCount) > (*tickLimit))
{
test->TestFalse(TEXT("Tick limit reached for this test. The Jet Location never changed from (0,0,0)."), *tickCount > *tickLimit);
return true;
}
}
}
}
return false;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FAJetShouldMoveWhenAccelerationAddedTest, "ProjectR.Unit.JetTests.ShouldMoveWhenAccelerationAdded", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::ProductFilter)
bool FAJetShouldMoveWhenAccelerationAddedTest::RunTest(const FString& Parameters)
{
{
FString testWorldName = FString("/Game/Tests/TestMaps/VoidWorld");
ADD_LATENT_AUTOMATION_COMMAND(FEditorLoadMap(testWorldName))
ADD_LATENT_AUTOMATION_COMMAND(FStartPIECommand(true));
ADD_LATENT_AUTOMATION_COMMAND(FSpawningAJetMakeItAccelerateCommand(this));
int* tickCount = new int{0};
int* tickLimit = new int{3};
ADD_LATENT_AUTOMATION_COMMAND(FCheckAJetLocationCommand(tickCount, tickLimit, this));
//ADD_LATENT_AUTOMATION_COMMAND(FEndPlayMapCommand);
}
return true;
}
#endif //WITH_DEV_AUTOMATION_TESTS