Dart DocumentationunittestTestCase

TestCase class

Represents the state for an individual unit test.

Create by calling test or solo_test.

class TestCase {
 /** Identifier for this test. */
 final int id;

 /** A description of what the test is specifying. */
 final String description;

 /** The setup function to call before the test, if any. */
 Function setUp;

 /** The teardown function to call after the test, if any. */
 Function tearDown;

 /** The body of the test case. */
 TestFunction testFunction;

 /**
  * Remaining number of callbacks functions that must reach a 'done' state
  * to wait for before the test completes.
  */
 int _callbackFunctionsOutstanding = 0;

 String _message = '';
 /** Error or failure message. */
 String get message => _message;

 String _result;
 /**
  * One of [PASS], [FAIL], [ERROR], or [null] if the test hasn't run yet.
  */
 String get result => _result;

 String _stackTrace;
 /** Stack trace associated with this test, or [null] if it succeeded. */
 String get stackTrace => _stackTrace;

 /** The group (or groups) under which this test is running. */
 final String currentGroup;

 DateTime _startTime;
 DateTime get startTime => _startTime;

 Duration _runningTime;
 Duration get runningTime => _runningTime;

 bool enabled = true;

 bool _doneTeardown = false;

 Completer _testComplete;

 TestCase._internal(this.id, this.description, this.testFunction)
 : currentGroup = _currentGroup,
   setUp = _testSetup,
   tearDown = _testTeardown;

 bool get isComplete => !enabled || result != null;

 void _prepTest() {
   _config.onTestStart(this);
   _startTime = new DateTime.now();
   _runningTime = null;
 }

 Future _runTest() {
   _prepTest();
   // Increment/decrement callbackFunctionsOutstanding to prevent
   // synchronous 'async' callbacks from causing the  test to be
   // marked as complete before the body is completely executed.
   ++_callbackFunctionsOutstanding;
   var f = testFunction();
   --_callbackFunctionsOutstanding;
   if (f is Future) {
     return f.then((_) => _finishTest())
      .catchError((e) => fail("${e.error}"));
   } else {
     _finishTest();
     return null;
   }
 }

 void _finishTest() {
   if (result == null && _callbackFunctionsOutstanding == 0) {
     pass();
   }
 }

 /**
  * Perform any associated [_setUp] function and run the test. Returns
  * a [Future] that can be used to schedule the next test. If the test runs
  * to completion synchronously, or is disabled, null is returned, to
  * tell unittest to schedule the next test immediately.
  */
 Future _run() {
   if (!enabled) return null;

   _result = _stackTrace = null;
   _message = '';
   _doneTeardown = false;
   var rtn = setUp == null ? null : setUp();
   if (rtn is Future) {
     rtn.then((_) => _runTest())
        .catchError((e) {
         _prepTest();
         // Calling error() will result in the tearDown being done.
         // One could debate whether tearDown should be done after
         // a failed setUp. There is no right answer, but doing it
         // seems to be the more conservative approach, because
         // unittest will not stop at a test failure.
         error("$description: Test setup failed: ${e.error}");
       });
   } else {
     var f = _runTest();
     if (f != null) {
       return f;
     }
   }
   if (result == null) { // Not complete.
     _testComplete = new Completer();
     return _testComplete.future;
   }
   return null;
 }

 void _notifyComplete() {
   if (_testComplete != null) {
     _testComplete.complete(this);
     _testComplete = null;
   }
 }

 // Set the results, notify the config, and return true if this
 // is the first time the result is being set.
 void _setResult(String testResult, String messageText, String stack) {
   _message = messageText;
   _stackTrace = stack;
   if (result == null) {
     _result = testResult;
     _config.onTestResult(this);
   } else {
     _result = testResult;
     _config.onTestResultChanged(this);
   }
 }

 void _complete(String testResult,
               [String messageText = '',
                String stack = '']) {
   if (runningTime == null) {
     _runningTime = new DateTime.now().difference(startTime);
   }
   _setResult(testResult, messageText, stack);
   if (!_doneTeardown) {
     _doneTeardown = true;
     if (tearDown != null) {
       var rtn = tearDown();
       if (rtn is Future) {
         rtn.then((_) {
           _notifyComplete();
         })
         .catchError((e) {
           // We don't call fail() as that will potentially result in
           // spurious messages like 'test failed more than once'.
           _setResult(ERROR, "$description: Test teardown failed: ${e.error}",
               e.stackTrace.toString());
           _notifyComplete();
         });
         return;
       }
     }
   }
   _notifyComplete();
 }

 void pass() {
   _complete(PASS);
 }

 void fail(String messageText, [String stack = '']) {
   if (result != null) {
     String newMessage = (result == PASS)
         ? 'Test failed after initially passing: $messageText'
         : 'Test failed more than once: $messageText';
     // TODO(gram): Should we combine the stack with the old one?
     _complete(ERROR, newMessage, stack);
   } else {
     _complete(FAIL, messageText, stack);
   }
 }

 void error(String messageText, [String stack = '']) {
   _complete(ERROR, messageText, stack);
 }

 void _markCallbackComplete() {
   if (--_callbackFunctionsOutstanding == 0 && !isComplete) {
     pass();
   }
 }
}

Properties

final String currentGroup #

The group (or groups) under which this test is running.

final String currentGroup

final String description #

A description of what the test is specifying.

final String description

bool enabled #

bool enabled = true

final int id #

Identifier for this test.

final int id

final bool isComplete #

bool get isComplete => !enabled || result != null;

final String message #

Error or failure message.

String get message => _message;

final String result #

One of PASS, FAIL, ERROR, or null if the test hasn't run yet.

String get result => _result;

final Duration runningTime #

Duration get runningTime => _runningTime;

Function setUp #

The setup function to call before the test, if any.

Function setUp

final String stackTrace #

Stack trace associated with this test, or null if it succeeded.

String get stackTrace => _stackTrace;

final DateTime startTime #

DateTime get startTime => _startTime;

Function tearDown #

The teardown function to call after the test, if any.

Function tearDown

TestFunction testFunction #

The body of the test case.

TestFunction testFunction

Methods

void error(String messageText, [String stack = '']) #

void error(String messageText, [String stack = '']) {
 _complete(ERROR, messageText, stack);
}

void fail(String messageText, [String stack = '']) #

void fail(String messageText, [String stack = '']) {
 if (result != null) {
   String newMessage = (result == PASS)
       ? 'Test failed after initially passing: $messageText'
       : 'Test failed more than once: $messageText';
   // TODO(gram): Should we combine the stack with the old one?
   _complete(ERROR, newMessage, stack);
 } else {
   _complete(FAIL, messageText, stack);
 }
}

void pass() #

void pass() {
 _complete(PASS);
}