Angelscript Test Support🔗
Angelscript features a xUnit-style unit testing framework. There is also an
integration test framework that can play back game scenarios and wait for
some condition to occur. You can generate code coverage reports for test
runs as well. FName
Unit Tests🔗
You can put test code in any Angelscript file, but by convention these are put in File_Test.as if your production code is in File.as.
Running Unit Tests🔗
Unit tests run on hot reload, so to run a test you just create a test like above, open the Unreal editor, and save the file. In Unreal, go Window > Developer Tools > Output Log and you will see lines like
Angelscript: [RUN] Some.Angelscript.Subdir.Test_LaunchesNukesWhenCodesAreEntered
...
Angelscript: [OK] Some.Angelscript.Subdir.Test_LaunchesNukesWhenCodesAreEntered (0.2530 ms)
Furthermore, the tests show up under the category "Angelscript" in the Test Automation tool. You will need to install that one into Unreal. See https://docs.unrealengine.com/en-US/Programming/Automation/UserGuide/index.html
You can also run tests from the command line:
Engine\Binaries\Win64\UE4Editor-Cmd.exe \Path\To\your.uproject -NullRHI -NoSound -NoSplash -ExecCmds="Automation RunTests Angelscript.UnitTests" -TestExit "Automation Test Queue Empty+Found 0 Automation Tests, based on" -unattended -stdout -as-exit-on-error
Installing a Custom Game Mode for Unit Tests🔗
You can add this line to one of your .ini files in your project to get a game mode in your tests: You can then create a blueprint at the specified location and put whatever settings you want in there. This will be used by all unit tests.
[/Script/EngineSettings.GameMapsSettings]
...
+GameModeClassAliases=(Name="UnitTest",GameMode="/Game/Testing/UnitTest/BP_UnitTestGameMode.BP_UnitTestGameMode_C")
Integration Tests🔗
Each integration test has a map where you can draw up any geometry or place any actors you like.
Add this to for instance MyTestName_IntegrationTest.as:
Then you need to add a test map IntegrationTest_MyTestName.umap to /Content/Testing/ (create the dir if you don't have it in your project yet). The map name is always the same as the test name, with .umap added.
You can also configure the integration test map dir with this setting in your .ini files:
[/Script/AngelscriptCode.AngelscriptTestSettings]
IntegrationTestMapRoot=/Game/Testing/
You can retrieve placed actors like this (or spawn them in the test):
Latent Automation Commands🔗
The code in the test function executes before the map is loaded and before the first frame executes. The test is not complete when the test function returns therefore, it has merely enqueued a series of latent automation commands (Unreal documentation). If we assume the test enqueues no latent commands of its own (like the one above), the test framework will enqueue the following actions (see IntegrationTest.cpp):
- FWaitForMapToLoadCommand()
- FEnsureWorldLoaded()
- FExitGameCommand()
- FReportFinished()
- FFreeTest()
These execute in sequence. Each action can take multiple engine frames to execute.
The test can enqueue latent commands of its own:
The action is enqueued using T.AddLatentAutomationCommand
. The set of latent actions will now be:
- ...
- FEnsureWorldLoaded()
- UGetsShowXTimes()
- FExitGameCommand()
- ...
AddLatentAutomationCommand takes a ULatentAutomationCommand
:
The game engine will keep ticking as long as Update returns false. This means you can wait on any condition you can think of. The default timeout is five seconds though, so you can't wait for too long.
You can specify default bAllowTimeout = true
on a latent command to allow it to time out. This is useful if you want to test that something is not happening
(e.g. check actor doesn't move out of bounds during 5 seconds).
Running Integration Tests🔗
Integration tests don't run on hot reload like unit tests, so you need to invoke them through the Test Automation window in Unreal. They are run just like unit tests, see above.
To run integration tests from the command line, run the same line as for unit tests but replace Angelscript.UnitTests with Angelscript.IntegrationTests.
Complex Integration Tests🔗
You can also generate test cases dynamically:
If we assume you have three potions in your potion registry, this generates three test cases:
Angelscript.IntegrationTest.Your.Path.ComplexIntegrationTest_PotionsAreTooStrongForKnight[DA_Potion1]
Angelscript.IntegrationTest.Your.Path.ComplexIntegrationTest_PotionsAreTooStrongForKnight[DA_Potion2]
Angelscript.IntegrationTest.Your.Path.ComplexIntegrationTest_PotionsAreTooStrongForKnight[DA_Potion3]
Code Coverage🔗
Enable code coverage in Project Settings > Editor > Angelscript Test settings (or pass -as-enable-code-coverage on the command line). Note, code coverage slows down editor startup by ~20 seconds so remember to turn it off later.
Run some tests as described above. The editor will write a report to Saved/CodeCoverage. Note: it's overwritten each time you start a new test run.
Open index.html to see a summary for all your angelscript.
Open individual files to see their line coverage.