UnitTest:
Filter:
Classes | Testing

UnitTest : Object

a class for programmatic testing of classes
Source: UnitTest.sc
Subclasses: UnitTestScript

Description

In order to make sure a method works correctly, a test can be implemented that assures the correct behavior.

It is a common practice to write tests to clarify how an object should respond, and it may avoid inconsistencies on the long run. A test is always a subclass of UnitTest, implementing at least one method starting with test_.

NOTE: UnitTests for the Common library classes are kept in the testsuite/classlibrary directory of the SuperCollider sources.

To install, download the sources and add the directory to your sclang_conf.yaml, either by editing it or via the ScIDE preferences.

Class Methods

UnitTest.gui

A graphical interface to run and browse all tests

UnitTest.gui

UnitTest.run(reset: true, report: true)

Run all methods whose names begin with test_.

TestUnitTest.new.run;

Arguments:

reset

If true, first runs *reset on the class.

report

If true, outputs the test results.

UnitTest.runTest(methodName)

Run a single test method.

UnitTest.reset;
UnitTest.runTest("TestUnitTest:test_assert");

Arguments:

methodName

A String referring to the class and test method within it, e.g. "TestPolyPlayerPool:test_prepareChildrenToBundle".

UnitTest.runAll

runs all subclasses of UnitTest

UnitTest.reset;
UnitTest.runAll;

Inherited class methods

Undocumented class methods

UnitTest.runTestClassForClass(class, reset: true, report: true)

Instance Methods

.runTestMethod(method)

Run a single test method of this class

TestUnitTest.new.runTestMethod(TestUnitTest.findMethod(\test_assert));

Arguments:

method

the method to run

Returns:

(describe returnvalue here)

.assert(boolean, message, report: true, onFailure)

Asserts that an expression must be true.

this.assert(2 == 2, "passes");
this.assert(2 == 2.00001, "fails");

Arguments:

boolean

A boolean, where true means that the test is passed.

message

A message describing the purpose of the assertion, e.g. "foo should be less than bar". Posted if report is true.

report

Reports the result of the test if true.

onFailure

If not nil, a failure stops the tests and evaluates this function.

.assertEquals(a, b, message: "", report: true, onFailure)

Asserts that an expression a is equal to the value b, where equality is determined according to a's implementation of ==.

this.assertEquals(2 + 2, 4, "passes");
this.assertEquals(2 + 2, 5, "fails");

Arguments:

a

the experimentally produced value

b

the expected value

message

A message describing the purpose of the assertion, e.g. "Adding two numbers should return their sum.". Posted if report is true.

report

Reports the result of the test if true (default is true)

onFailure

If not nil, a failure stops the tests and evaluates this function.

.assertFloatEquals(a, b, message: "", within: 0.0001, report: true, onFailure)

Asserts that an expression a returning a float is within a given range (within) of being equal to b.

this.assertFloatEquals(2, 2.0001, "Pass since 2 is close enough to 2.0001.", 0.001);
this.assertFloatEquals(2, 2.0001, "Fail since 2 isn't close enough to 2.0001.", 0.0001);

Arguments:

a

the experimentally produced float value

b

the expected float value

message

A message describing the purpose of the assertion, e.g. "Adding two numbers should return their sum.". Posted if report is true.

within

The range within which a must be of b in order for the test to pass.

report

Reports the result of the test if true (default is true)

onFailure

If not nil, a failure stops the tests and evaluates this function.

.assertArrayFloatEquals(a, b, message: "", within: 0.0001, report: true, onFailure)

Make sure that the two arrays of floats a and b equal within a given range (within).

this.assertArrayFloatEquals([2, 3] + 0.0001, [2, 3], "Pass since pairs of floats are close enough", 0.001);
this.assertArrayFloatEquals([2, 3.0001], [2, 3], "Fail since pairs of floats aren't both close enough", 0.0001);

Arguments:

a

the experimentally produced value, which is an Array of floats

b

the Array of float values expected

message

A message describing the purpose of the assertion, e.g. "Arrays foo and bar should be equal.". Posted if report is true.

within

The range within which each item of a must be of the corresponding item in b in order for the test to pass.

report

Reports the result of the test if true (default is true)

onFailure

If not nil, a failure stops the tests and evaluates this function.

.ifAsserts(boolean, message, ifPassedFunc, ifFailedFunc, report: true)

Make a further assertion only if it passed, or only if it failed.

(
a = UnitTest.new;
a.ifAsserts(2 == 3, "yes", { a.assert(2 == 4) }, { a.assert(1 == 1, "but this is correct") });
)

.wait(condition, failureMessage, maxTime: 10)

Wait for a condition, consider failed after maxTime. Only valid within a test (or a routine).

(
{
    s.reboot;
    UnitTest.new.wait(s.serverRunning, "server failed to boot in time", 2);
}.fork
)

.bootServer(server)

Wait for server boot until continued. Only valid within a test (or a routine).

If already booted, then freeAll and create new allocators.

(
{
    UnitTest.new.bootServer(s);
}.fork
)

.passed(method, message, report: true)

Register a passed test.

this.passed(message: "this passed");

.failed(method, message, report: true)

Register a test failure.

this.failed(message: "this failed");

Inherited instance methods

Undocumented instance methods

.asynchAssert(waitConditionBlock, testBlock, timeoutMessage: "", timeout: 10)

Examples

Write tests by subclassing UnitTest, and defining methods whose names begins test_. Each test method will be called from a fresh instance of the subclass.

If you implement the methods setUp and tearDown in your test class, they will be called before and after every test. This can help to eliminate repetitive code, and makes it easier to maintain your tests by ensuring that they all run under the same set of conditions.

TestYourClass : UnitTest {
    setUp {
        // this will be called before each test
    }
    tearDown {
        // this will be called after each test
    }

    test_yourMethod {
        // every method whose name begins with "test_" will be run

        this.assert( 6 == 6, "6 should equal 6");

        this.assertEquals( 9, 9, "9 should equal 9");

        this.assertFloatEquals( 4.0 , 1.0 * 4.0 / 4.0  4.0,
            "floating point math should be close to equal");

        // we are inside a Routine, you may wait
        1.0.wait;

        // this will wait until the server is booted
        this.bootServer;

        // if the server is already booted it will free all nodes
        // and create new allocators, giving you a clean slate
        p = { SinOsc.ar };
        p.play;
        p.register;
        // will wait until the condition is true
        // will be considered a failure after 10 seconds
        this.wait( { p.isPlaying }, "waiting for synth to play", 10);
    }
}