Dart API ReferenceunittestConfiguration

Configuration class

Hooks to configure the unittest library for different platforms. This class implements the API in a platform-independent way. Tests that want to take advantage of the platform can create a subclass and override methods from this class.

class Configuration {
 // The VM won't shut down if a receive port is open. Use this to make sure
 // we correctly wait for asynchronous tests.
 ReceivePort _receivePort;

 /**
  * Subclasses can override this with something useful for diagnostics.
  * Particularly useful in cases where we have parent/child configurations
  * such as layout tests.
  */
 final String name = 'Configuration';

 /**
  * If true, then tests are started automatically (otherwise [runTests]
  * must be called explicitly after the tests are set up.
  */
 final bool autoStart = true;

 /**
  * If true (the default), throw an exception at the end if any tests failed.
  */
 bool throwOnTestFailures = true;

 /**
  * If true (the default), then tests will stop after the first failed
  * [expect]. If false, failed [expect]s will not cause the test
  * to stop (other exceptions will still terminate the test).
  */
 bool stopTestOnExpectFailure = true;

 // If stopTestOnExpectFailure is false, we need to capture failures, which
 // we do with this List.
 List _testLogBuffer = new List();
 
 /**
  * The constructor sets up a failure handler for [expect] that redirects
  * [expect] failures to [onExpectFailure].
  */
 Configuration() {
   configureExpectFailureHandler(new _ExpectFailureHandler(this));
 }
 /**
  * Called as soon as the unittest framework becomes initialized. This is done
  * even before tests are added to the test framework. It might be used to
  * determine/debug errors that occur before the test harness starts executing.
  * It is also used to tell the vm or browser that tests are going to be run
  * asynchronously and that the process should wait until they are done.
  */
 void onInit() {
   _receivePort = new ReceivePort();
   _postMessage('unittest-suite-wait-for-done');
 }

 /** Called as soon as the unittest framework starts running. */
 void onStart() {}

 /**
  * Called when each test starts. Useful to show intermediate progress on
  * a test suite. Derived classes should call this first before their own
  * override code.
  */
 void onTestStart(TestCase testCase) {
   assert(testCase != null);
   _testLogBuffer.clear();
 }

 /**
  * Called when each test is first completed. Useful to show intermediate
  * progress on a test suite. Derived classes should call this first 
  * before their own override code.
  */
 void onTestResult(TestCase testCase) {
   assert(testCase != null);
   if (!stopTestOnExpectFailure && _testLogBuffer.length > 0) {
     // Write the message/stack pairs up to the last pairs.
     var reason = new StringBuffer();
     for (var i = 0; i < _testLogBuffer.length - 2; i += 2) {
       reason.write(_testLogBuffer[i]);
       reason.write('\n');
       reason.write(_formatStack(_testLogBuffer[i+1]));
       reason.write('\n');
     }
     // Write the last message.
     reason.write(_testLogBuffer[_testLogBuffer.length - 2]);
     if (testCase.result == PASS) {
       testCase._result = FAIL;
       testCase._message = reason.toString();
       // Use the last stack as the overall failure stack.    
       testCase._stackTrace = 
           _formatStack(_testLogBuffer[_testLogBuffer.length - 1]);
     } else {
       // Add the last stack to the message; we have a further stack
       // caused by some other failure.
       reason.write(_formatStack(_testLogBuffer[_testLogBuffer.length - 1]));
       reason.write('\n');
       // Add the existing reason to the end of the expect log to 
       // create the final message.
       testCase._message = '${reason.toString()}\n${testCase._message}';
     }
   }
 }

 /**
  * Called when an already completed test changes state; for example a test
  * that was marked as passing may later be marked as being in error because
  * it still had callbacks being invoked.
  */
 void onTestResultChanged(TestCase testCase) {
   assert(testCase != null);
 }

 /**
  * Handles the logging of messages by a test case. The default in
  * this base configuration is to call print();
  */
 void onLogMessage(TestCase testCase, String message) {
   print(message);
 }

 /**
  * Handles failures from expect(). The default in
  * this base configuration is to throw an exception;
  */
 void onExpectFailure(String reason) {
   if (stopTestOnExpectFailure) {
     throw new TestFailure(reason);
   } else {
     _testLogBuffer.add(reason);
     try {
       throw '';
     } catch (_, stack) {
       _testLogBuffer.add(stack);
     }
   }
 }
 
 /**
  * Format a test result.
  */
 String formatResult(TestCase testCase) {
   var result = new StringBuffer();
   result.write(testCase.result.toUpperCase());
   result.write(": ");
   result.write(testCase.description);
   result.write("\n");

   if (testCase.message != '') {
     result.write(_indent(testCase.message));
     result.write("\n");
   }

   if (testCase.stackTrace != null && testCase.stackTrace != '') {
     result.write(_indent(testCase.stackTrace));
     result.write("\n");
   }
   return result.toString();
 }

 /**
  * Called with the result of all test cases. The default implementation prints
  * the result summary using the built-in [print] command. Browser tests
  * commonly override this to reformat the output.
  *
  * When [uncaughtError] is not null, it contains an error that occured outside
  * of tests (e.g. setting up the test).
  */
 void onSummary(int passed, int failed, int errors, List<TestCase> results,
     String uncaughtError) {
   // Print each test's result.
   for (final t in results) {
     print(formatResult(t));
   }

   // Show the summary.
   print('');

   if (passed == 0 && failed == 0 && errors == 0 && uncaughtError == null) {
     print('No tests found.');
     // This is considered a failure too.
   } else if (failed == 0 && errors == 0 && uncaughtError == null) {
     print('All $passed tests passed.');
   } else {
     if (uncaughtError != null) {
       print('Top-level uncaught error: $uncaughtError');
     }
     print('$passed PASSED, $failed FAILED, $errors ERRORS');
   }
 }

 /**
  * Called when the unittest framework is done running. [success] indicates
  * whether all tests passed successfully.
  */
 void onDone(bool success) {
   if (success) {
     _postMessage('unittest-suite-success');
     _receivePort.close();
   } else {
     _receivePort.close();
     if (throwOnTestFailures) {
       throw new Exception('Some tests failed.');
     }
   }
 }

 String _indent(String str) {
   // TODO(nweiz): Use this simpler code once issue 2980 is fixed.
   // return str.replaceAll(new RegExp("^", multiLine: true), "  ");

   return str.split("\n").map((line) => "  $line").join("\n");
 }

 /** Handle errors that happen outside the tests. */
 // TODO(vsm): figure out how to expose the stack trace here
 // Currently e.message works in dartium, but not in dartc.
 void handleExternalError(e, String message, [String stack = '']) =>
     _reportTestError('$message\nCaught $e', stack);

 _postMessage(String message) {
   // In dart2js browser tests, the JavaScript-based test controller
   // intercepts calls to print and listens for "secret" messages.
   print(message);
 }
}

Constructors

new Configuration() #

The constructor sets up a failure handler for expect that redirects expect failures to onExpectFailure.

Configuration() {
 configureExpectFailureHandler(new _ExpectFailureHandler(this));
}

Properties

final bool autoStart #

If true, then tests are started automatically (otherwise runTests must be called explicitly after the tests are set up.

final bool autoStart = true

final String name #

Subclasses can override this with something useful for diagnostics. Particularly useful in cases where we have parent/child configurations such as layout tests.

final String name = 'Configuration'

bool stopTestOnExpectFailure #

If true (the default), then tests will stop after the first failed expect. If false, failed expects will not cause the test to stop (other exceptions will still terminate the test).

bool stopTestOnExpectFailure = true

bool throwOnTestFailures #

If true (the default), throw an exception at the end if any tests failed.

bool throwOnTestFailures = true

Methods

String formatResult(TestCase testCase) #

Format a test result.

String formatResult(TestCase testCase) {
 var result = new StringBuffer();
 result.write(testCase.result.toUpperCase());
 result.write(": ");
 result.write(testCase.description);
 result.write("\n");

 if (testCase.message != '') {
   result.write(_indent(testCase.message));
   result.write("\n");
 }

 if (testCase.stackTrace != null && testCase.stackTrace != '') {
   result.write(_indent(testCase.stackTrace));
   result.write("\n");
 }
 return result.toString();
}

void handleExternalError(e, String message, [String stack = '']) #

Handle errors that happen outside the tests.

void handleExternalError(e, String message, [String stack = '']) =>
   _reportTestError('$message\nCaught $e', stack);

void onDone(bool success) #

Called when the unittest framework is done running. success indicates whether all tests passed successfully.

void onDone(bool success) {
 if (success) {
   _postMessage('unittest-suite-success');
   _receivePort.close();
 } else {
   _receivePort.close();
   if (throwOnTestFailures) {
     throw new Exception('Some tests failed.');
   }
 }
}

void onExpectFailure(String reason) #

Handles failures from expect(). The default in this base configuration is to throw an exception;

void onExpectFailure(String reason) {
 if (stopTestOnExpectFailure) {
   throw new TestFailure(reason);
 } else {
   _testLogBuffer.add(reason);
   try {
     throw '';
   } catch (_, stack) {
     _testLogBuffer.add(stack);
   }
 }
}

void onInit() #

Called as soon as the unittest framework becomes initialized. This is done even before tests are added to the test framework. It might be used to determine/debug errors that occur before the test harness starts executing. It is also used to tell the vm or browser that tests are going to be run asynchronously and that the process should wait until they are done.

void onInit() {
 _receivePort = new ReceivePort();
 _postMessage('unittest-suite-wait-for-done');
}

void onLogMessage(TestCase testCase, String message) #

Handles the logging of messages by a test case. The default in this base configuration is to call print();

void onLogMessage(TestCase testCase, String message) {
 print(message);
}

void onStart() #

Called as soon as the unittest framework starts running.

void onStart() {}

void onSummary(int passed, int failed, int errors, List<TestCase> results, String uncaughtError) #

Called with the result of all test cases. The default implementation prints the result summary using the built-in print command. Browser tests commonly override this to reformat the output.

When uncaughtError is not null, it contains an error that occured outside of tests (e.g. setting up the test).

void onSummary(int passed, int failed, int errors, List<TestCase> results,
   String uncaughtError) {
 // Print each test's result.
 for (final t in results) {
   print(formatResult(t));
 }

 // Show the summary.
 print('');

 if (passed == 0 && failed == 0 && errors == 0 && uncaughtError == null) {
   print('No tests found.');
   // This is considered a failure too.
 } else if (failed == 0 && errors == 0 && uncaughtError == null) {
   print('All $passed tests passed.');
 } else {
   if (uncaughtError != null) {
     print('Top-level uncaught error: $uncaughtError');
   }
   print('$passed PASSED, $failed FAILED, $errors ERRORS');
 }
}

void onTestResult(TestCase testCase) #

Called when each test is first completed. Useful to show intermediate progress on a test suite. Derived classes should call this first before their own override code.

void onTestResult(TestCase testCase) {
 assert(testCase != null);
 if (!stopTestOnExpectFailure && _testLogBuffer.length > 0) {
   // Write the message/stack pairs up to the last pairs.
   var reason = new StringBuffer();
   for (var i = 0; i < _testLogBuffer.length - 2; i += 2) {
     reason.write(_testLogBuffer[i]);
     reason.write('\n');
     reason.write(_formatStack(_testLogBuffer[i+1]));
     reason.write('\n');
   }
   // Write the last message.
   reason.write(_testLogBuffer[_testLogBuffer.length - 2]);
   if (testCase.result == PASS) {
     testCase._result = FAIL;
     testCase._message = reason.toString();
     // Use the last stack as the overall failure stack.    
     testCase._stackTrace = 
         _formatStack(_testLogBuffer[_testLogBuffer.length - 1]);
   } else {
     // Add the last stack to the message; we have a further stack
     // caused by some other failure.
     reason.write(_formatStack(_testLogBuffer[_testLogBuffer.length - 1]));
     reason.write('\n');
     // Add the existing reason to the end of the expect log to 
     // create the final message.
     testCase._message = '${reason.toString()}\n${testCase._message}';
   }
 }
}

void onTestResultChanged(TestCase testCase) #

Called when an already completed test changes state; for example a test that was marked as passing may later be marked as being in error because it still had callbacks being invoked.

void onTestResultChanged(TestCase testCase) {
 assert(testCase != null);
}

void onTestStart(TestCase testCase) #

Called when each test starts. Useful to show intermediate progress on a test suite. Derived classes should call this first before their own override code.

void onTestStart(TestCase testCase) {
 assert(testCase != null);
 _testLogBuffer.clear();
}