User Tools

Site Tools


Sidebar

Jump to
AmbientTalk
CRIME
iScheme

at:tutorial:appendix

This is an old revision of the document!


Appendix

In the appendix, we explain useful libraries available to the AmbientTalk/2 programmer.

Unit Testing Framework

The file at/unit/test.at shipped with the AmbientTalk/2 system library defines a unit testing framework for AmbientTalk/2 which is similar in spirit and structure to JUnit and SUnit. Load the module by executing import /.at.unit.test.

Creating a Unit Test

To create your own unit test, make an extension of the UnitTestobject which is exported by the unit testing module. In the extension, define zero-arity methods starting with the prefix test. Here is an example:

def myUnitTest := extend: UnitTest.new("my unit test") with: {
  def testSomething() {
    self.assertEquals(3,1+2);
  }
}

You can run a unit test by sending to your unit test object the message runTest(), for example:

myUnitTest.runTest()

This will execute all test* methods in the given unit test, and print out which of the tests succeeded or failed. The runTest method can optionally take a “reporter” object as an argument, which can be used to implement a custom strategy for reporting success or failure of a unit test. The default reporter object is a text-based UI.

Like in JUnit and SUnit, it is possible to define two methods named setUp() and tearDown() that are invoked in between each individual test* method.

Assertions

Within a test* method, you can use a number of assertion methods to assert certain properties of your code:

assertTrue(boolean)
assertFalse(boolean)
assertEquals(o1,o2)
assertNotEquals(o1,o2) 
assertLessThan(o1,o2)
assertGreaterThan(o1,o2) 
assertLessThanOrEquals(o1,o2) 
assertGreaterThanOrEquals(o1,o2)
assertMatches(str, pattern)
assertNotNil(val)

Each of these methods also takes as an optional last parameter a reason, which is a text string describing what the assertion checks. This string is printed when the assertion fails and can be used to provide more understandable error messages.

Finally, two more useful auxiliary methods exist:

assert: exceptionType raisedIn: closure
fail(reason)

The assert:raisedIn: method executes the given closure and checks whether this leads to an exception of type exceptionType. If so, the exception is caught and further ignored. If no exception (or one of the wrong type) is raised, the assertion will fail. The fail method can be used to explicitly make a unit test fail with a given reason.

Be sure to invoke the above assertion methods by means of self-sends as shown in the above example! These methods are defined in the UnitTest parent object, not in the global lexical scope.

Asynchronous Unit Tests

When a method is prefixed with 'testAsync', the unit testing framework expects the method to return a future and will only process subsequent test methods once the future is resolved/ruined. This is useful for performing unit tests that require asynchronous message sends.

Test Suites

It is possible to group multiple unit test objects into what is known as a “test suite”. Running the test suite runs all of the component unit tests. You can create a new test suite as follows:

def myTestSuite := TestSuite.new("my test suite",
  [unittest1,
   unittest2,
   ... ]);

The TestSuite object groups the given unit test objects. You can execute all tests in batch by sending the test suite object the runTest message, just like for running a single unit test. It is possible to nest multiple test suites within each other.

at/tutorial/appendix.1215509467.txt.gz · Last modified: 2008/07/08 11:46 (external edit)