Sunday, December 9, 2012

Trying to Test Client Side Dart

‹prev | My Chain | next›

My efforts to rebase the various branches in Dart Comics onto a base updated for the M1 release proceed apace. After tonight, I think all that remains is the websocket branch. But first, an issue found by my new favorite tool, the dart_analyzer.

At one point, I had played with exceptions in Dart and it is this that is breaking for me now. Specifically, according to dart_analyzer, exceptions now follow a new format:
➜  scripts git:(mvc-futures) dart_analyzer main.dart
file:/home/chris/repos/dart-comics/public/scripts/Views.AddComicForm.dart:98: This style of catch clause has been deprecated. Please use the 'on' <type> 'catch' '(' <identifier> (',' <identifier>)? ')' form.
    97:     }
    98:     catch (Exception e) {
                  ~
Compilation failed with 1 problem.
I fixed a similar issue a while back. As the analyzer says, all I need to do is reformat the catch. And in this case, since I am not trying to catch anything other than the high top-level Exception class, I can catch with no type:
    try {
      collection.create({
        'title':title.value,
        'author':author.value
      });
    }
    catch (e) {
      print("Exception handled: ${e.type}");
    }
That solves my problems as far as dart_analyzer is concerned, but this seems like a good time to try to test exceptions. Looking through unittest, there seems to be only expectThrow for working with expectations. It is marked as deprecated. But, since there is no indication of what it is deprecated in favor of, I will give it a go anyhow.

Way back in the day, I had tried out some very early Dart unit testing in this sample application. I still have the remnants in the tests sub-directory, so I start building new tests right alongside the old (maybe I will update the old next). But when I try to run the empty test file as a sanity test, I get errors about not being able to find the unittest library:
➜  dart-comics git:(mvc-futures) ✗ dart tests/Views.AddComicFormTest.dart
Unable to open file: /home/chris/repos/dart-comics/tests/packages/unittest/unittest.dart'file:///home/chris/repos/dart-comics/tests/Views.AddComicFormTest.dart': Error: line 1 pos 1: library handler failed
import 'package:../unittest/unittest.dart';
^
The pubspec.yaml file in my application's root directory includes unittest.dart and it is definitely installed:
➜  dart-comics git:(mvc-futures) ✗ cat pubspec.yaml 
name: Dart Comics
dependencies:
  dirty: any
  uuid: any
  unittest:
    sdk: unittest
➜  dart-comics git:(mvc-futures) ✗ ls packages 
dirty  unittest  uuid
Eventually, I realize that, if I name my testing directory as test instead of tests, then Dart Pub will create a link to the packages directory:
➜  dart-comics git:(mvc-futures) ✗ rm -rf test
➜  dart-comics git:(mvc-futures) ✗ mkdir test
➜  dart-comics git:(mvc-futures) ✗ pub install
Resolving dependencies...
Dependencies installed!
➜  dart-comics git:(mvc-futures) ✗ ls -l test
total 0
lrwxrwxrwx 1 chris chris 38 Dec  9 23:16 packages -> /home/chris/repos/dart-comics/packages
So it seems that test is the official sub-directory for Dart testing.

Next up is the question of how to test client-side code. Back in the day, I had to setup a web page so that the test suite could run in Dartium. It seems as though something like this is still going to be required. I had expected trouble when some of my code tried to access document in the DOM, but my empty unit test crashes before it even reaches that. It crashes when the library being tested tries to import dart:html:
➜  dart-comics git:(mvc-futures) ✗ dart test/Views.AddComicForm_test.dart
Do not know how to load 'dart:html''file:///home/chris/repos/dart-comics/public/scripts/Views.AddComicForm.dart': Error: line 3 pos 1: library handler failed
import 'dart:html';
^
'file:///home/chris/repos/dart-comics/test/Views.AddComicForm_test.dart': Error: line 3 pos 1: library handler failed
import '../public/scripts/Views.AddComicForm.dart';
^
Bummer.

It seems that I still cannot escape the need for a browser when testing client-side Dart code. To get started with that, I create a sanity-check test:
import 'package:unittest/unittest.dart';

import '../public/scripts/Views.AddComicForm.dart';

main() {
  test('Sanity check', (){
    Expect.equals(1+1, 2);
  });

}
Then I load my test suite via a script src tag:
<html>
<head>
  <title>Hipster Test Suite</title>
  <script type="application/dart" src="Views.AddComicForm_test.dart"></script>

  <script type="text/javascript">
    // start dart
    navigator.webkitStartDart();
  </script>
</head>

<body>
<h1>Test!</h1>

</body>
</html>
And yup, in the Dart console, that test passes:


That's a roundabout way to make progress, but I call it a day there. I ultimately need a way to run tests under continuous integration and this seems lacking right now. I may explore the browser testing a bit more tomorrow.


Day #594

No comments:

Post a Comment