Tuesday, February 21, 2012

Getting Started with Dart Testing

‹prev | My Chain | next›

I am somewhat test obsessed. I have been exploring Dart for nearly 2 months and have not even considered testing, which is why I am only somewhat test obsessed. But tonight I can ignore the nagging doubts no longer.

One of the reasons that I have yet to do much with testing is that Dart does not bundle a unit testing framework—at least not yet. There is some test framework stuff in the bleeding edge at: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/testing/.

So first, I install subversion (seriously, who still uses subversion?):
sudo apt-get install subversion
Then I can checkout the testing path:
➜  tmp  svn co http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/testing/
A    testing/unittest
A    testing/unittest/shared.dart
A    testing/unittest/dom_for_unittest.js
A    testing/unittest/unittest.dart
A    testing/unittest/coverage_controller.js
A    testing/unittest/unittest_vm.dart
A    testing/unittest/dom_for_unittest.dart
A    testing/unittest/test_controller.js
A    testing/unittest/unittest_node.dart
A    testing/unittest/unittest_dartest.dart
A    testing/dartest
A    testing/dartest/dartest.dart
A    testing/dartest/css.dart
A    testing/dartest/resources
A    testing/dartest/resources/expand.png
A    testing/dartest/resources/min.png
A    testing/dartest/resources/close.png
A    testing/dartest/resources/max.png
A    testing/dartest/resources/img2base64.py
A    testing/dartest/README.txt
Checked out revision 4421.
Lastly, I remove subversion, just on principle:
➜  tmp  sudo apt-get remove subversion
It seems as though this is meant to be run in the browser (I would hazard a guess that it needs to be Dartium)—the README mentions an overlay window and the libraries make use of dart:html. So I create a test HTML in the testing directory with a reference to the Dart code being tested:
<html>
<head>
  <script type="application/dart" src="test.dart"></script>

  <!-- Start the dart engine -->
  <script type="text/javascript">
    if (navigator.webkitStartDart) {
      navigator.webkitStartDart();
    }
  </script>
</head>
<body>
<h1>Test!</h1>

</body>
</html>
As for the test.dart test code, I copy the #import() statements and test from the README (the myAddFunc() function is my own!):
#import('unittest/unittest_dartest.dart');
#import('dartest/dartest.dart');

main() {
  test('Test Description',(){
    Expect.equals(3, myAddFunc(1,2));
  });
  new DARTest().run();
}

int myAddFunc(int x, int y) => x + y;
Loading this up in Dartium, I see an overlay for test results, but no actual results. I also see a bunch of red in the Javascript, er... Dart console:


In the hopes that this a function of using an older version of Dartium, I grab the latest available from the Dartium download page and try again. Unfortunately, I receive the same error:
Exception: String expected
Stack Trace:  0. Function: 'NodeImplementation.set:textContent' url: '/mnt/data/b/build/slave/dartium-lucid64-inc/build/src/out/Release/obj/gen/webkit/bindings/dart/generated/dart/NodeImplementation.dart' line:52 col:3
 1. Function: 'DARTest._addTestDetails@5f927d8' url: 'file:///home/cstrom/repos/dart-comics/testing/dartest/dartest.dart' line:131 col:24
 2. Function: 'DARTest.function' url: 'file:///home/cstrom/repos/dart-comics/testing/dartest/dartest.dart' line:80 col:22
 3. Function: 'GrowableObjectArray.forEach' url: 'bootstrap_impl' line:1303 col:8
 4. Function: 'DARTest._createResultsTable@5f927d8' url: 'file:///home/cstrom/repos/dart-comics/testing/dartest/dartest.dart' line:76 col:18
 5. Function: 'DARTest.run' url: 'file:///home/cstrom/repos/dart-comics/testing/dartest/dartest.dart' line:58 col:24
 6. Function: '::main' url: 'file:///home/cstrom/repos/dart-comics/testing/test.dart' line:8 col:20
Line 131 for darttest.dart attempts to assign testId.textContent:
  void _addTestDetails(TestCase t, HTMLTableRowElement row) {
    HTMLTableCellElement testId = _runnerWindow.document.createElement('td');
    testId.textContent = t.id;
    // ...
  }
Since the exception states that a string was expected, the smallest change that might do something is to tack on a toString() call:
  void _addTestDetails(TestCase t, HTMLTableRowElement row) {
    HTMLTableCellElement testId = _runnerWindow.document.createElement('td');
    testId.textContent = t.id.toString();
    // ...
  }
That resolves the stack trace, but I am not quite sure that it worked. The results overlay seems oddly free of green:


Ah ha! It seems that I need to manually run my test suite by clicking on that play button. When I do so, I see green:


If I intentionally break the test:
  test('Test Description',(){
    Expect.equals(42, myAddFunc(1,2));
  });
Then, when I reload and run my suite again, I see red. I can even click on the failing spec to get a good idea what went wrong:


That is a good stopping point for today. The Coverage tab is not working for me, so I may pick up with that tomorrow. Then again, I am eager to see how this plays with live code, so I may ignore the Coverage tab for a little while longer.


Day #303

3 comments:

  1. Great post, thanks for sharing.
    If you don't like git you could also do
    git-svn clone REPO_URL.

    ReplyDelete
    Replies
    1. I mean if you don't like svn sorry ;)

      Delete
    2. Hahaha. It's more fun to whine about subversion than it is to do something proactive like use git-svn :P

      Actually, I do have git-svn installed, but try not to use it much because I don't like waiting for it to build the index from SVN history. Crazy as it seems, for small stuff like this, it seems faster to apt-get install subversion, checkout the repo, then remove subversion. Plus I like whining.

      Delete