I don't need to test my programs. I have an error-correcting modem.

Legacy:UsUnit

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

UsUnit is an UnrealScript Unit Testing Framework, much like JUnit and DUnit being developed by El Muerte.

Wikipedia:Unit testing makes it easier to validate correct behavior of the program during development. Tests can be seperated from the base code and can easily be rerun in order to validate if the changes made didn't break functionality.

Unit testing might seem like a lot of work, but there's a huge gain in the end.

The UsUnit Testing Framework is released under the LesserOpenUnrealModLicense, this means you can use it without limitations (even for commercial products).

Note: never include the UsUnit package and related tests with your game\mod. It should not belong in there, so make sure you don't create dependencies on UsUnit in your base code.

Usage

All UsUnit classes use the same external configuration file: UsUnit.ini

TestRunner

This is the main class that will run all given test cases and suites. There are a few ways to execute the TestRunner.

ServerActor
Simply add UsUnit.TestRunner to the ServerActors list and start a server. The tests will be started depending on the fDelayedStart value of the TestRunner.
WebAdmin
Upon installation of UsUnit via the ut4mod the webadmin module will automatically be registered. All you have to do is to enable the webadmin, start a server and visit the WebAdmin page.
Mutator
A mutator is included that can also start the test runner. The mutator name is UsUnit.UsUnitMutator. The mutator is current in the beta stage. You can start the test runner and view some results. But that is pretty much it.

Configuration

By default TestRunner doesn't do much. You will have to define which tests to run. This can be done directly in the main configuration file UsUnit.ini or via the WebAdmin.

[UsUnit.TestRunner]
Tests=MyTests.CASE_StartupTest
Tests=MyTests.SUITE_Algorithms
fDelayedStart=0
Tests
this is a dynamic string array containing the fully qualified names of the test cases and suites to execute. They will be executed in that order. By default this list is empty.
fDelayedStart
this defines the number of seconds to wait before automatically starting the tests. When it's set to 0 it will start the tests as soon as the TestRunner has been spawned. If the value is negative it will not start the tests automatically, it will wait until the run command is explicitly called. fDelayedStart is only used when it's started as a ServerActor.

TestReporter

The TestReporter is resposible for reporting the test progress and results. The TestReporter can have multiple output modules. The following come standard with the UsUnit package:

Output_HTML
This will produce a HTML file in the UserLogs directory containing the results of the tests.

Configuration

[UsUnit.TestReporter]
bGenerateLogErrors=true
OutputClasses=UsUnit.Output_HTML
bGenerateLogErrors
This will generate "error" log entries in the main log file. These can be parsed by a program to find the exact location of the check that failed. For this to work best you should use UCPP and the correct macros (that come with the UsUnit package).
OutputClasses
A dynamic string list containing all output modules to use.

Creating a test case

A test case extends the actor TestCase. This class will contain the code that performs the actual tests can checks. A normal test run will be like this:

  1. TestCase.setUp()
  2. TestCase.run()
    1. perform tests
    2. call done()
  3. TestCase.tearDown()

Note: test cases are spawned only once and never destroyed (not until a level restart). If your tests needs to initialize some data before the test is actually executed implement the setUp function, do not use any of the BeginPlay events.

The most important thing you need to do for a test case is implement the run() function. After you performed all tests in this test case you should call the function done(), if you do not do this the test cycle will never be completed.

Properties

TestName
a human readable name for the test
TestDescription
a short description of the test

Events

run()
will be called to run the test. You need to implement this.
setUp()
will be called right before run() is called, but outside the timed section. Use it to initialize data.
tearDown()
will be called after the test case was completed, but outside the timed section. Use it to clean up data.

Functions

Check(bool expression, coerce string message)
the actual check if a given condition results in true. If the condition given by expression is false this check failed. message contains a description of the current test.
Done()
this function must be called after all checks have been performed, otherwise the test cycle will not continue.

UCPP Notice

UsUnit comes with a macro file (UsUnit/macros.inc) that can be used with UCPP. This will add some extra magic to the Check functions. The following macros are defined:

CHECK(expr,msg)
this behaves much like the normal Check function, except that it will append the current filename and line where this function was called. This can be useful to find the check that failed.
CHECK(expr)
this will be translated to CHECK(expr,"expr"). In other words, the expression content will be converted to the description. This makes it easier in some cases like: CHECK(1+1 == 2).

To use the macro file simply add the following line before you call any CHECK:

#pragma ucpp include ../../UsUnit/macros.inc

Note: make sure you read the UCPP instructions on how to use it.

Example Test Case

More examples can be found in the UsUnitExamples package.

#pragma ucpp notice - precompile this unit with UCPP
#pragma ucpp version
// include the CHECK() macros to add filenames and location
#pragma ucpp include ../../UsUnit/macros.inc
 
class TEST_SimpleTests extends TestCase;
 
function run()
{
    local array<string> dummy;
    CHECK(1+1 == 2);
    CHECK("CaseInsensitive" ~= "caseinsensitive");
    CHECK(false, "false; will always fail");
    CHECK(split("one two three four five", " ", dummy) == 5, "\"one two three four five\" has 5 words");
    CHECK(split("one", " ", dummy) == 1, "\"one\" is 1 word");
    CHECK(round(1.5) == 2);
    CHECK(int(1.5) == 1);
    done();
}
 
defaultproperties
{
    TestName="Simple Tests"
    TestDescription="Example test case, performs some simple tests basic math testing."
}

Creating a Test Suite

A test suite is nothing more than a collection of test cases and\or test suites to be executed sequentially. A test suite extends the class TestSuite. It usually doesn't contain any code, just values in the defaultproperties section.

The following class properties are of interest:

TestName
the name of the suite
TestDescription
a short description of the test suite (optional)
TestClasses
a dynamic array with class references to test cases and test suites that are part of this suite.
bBreakOnFail
if set to true it will it will not continue with the next test class when the current class failed a single check. Default: true

Example Test Suite

class SUITE_ExampleSuite extends TestSuite;
 
defaultproperties
{
    TestName="Example Test Suite"
    TestDescription="Bundles all example tests from the UsUnitExamples package"
 
    TestClasses[0]=class'TEST_SimpleTests'
    TestClasses[1]=class'TEST_TimedTest'
}

Downloads

Development releases

Not really releases but just the lastest updates of the UsUnit packages straight from the CVS

CVS Access

Anonymous access
:pserver:anonymous@el-muerte.student.utwente.nl:/usr/local/cvsroot/UT2004
Module names
UsUnit
UsUnitExamples

Additional Information