Saturday, December 22, 2012

Testing Print Output in Dart

‹prev | My Chain | next›

While working through the process of converting code samples in Dart for Hipsters, I ran into a small problem with printing examples. I am converting the code samples from (mostly) inline examples to external, tested files. The problem is that several of the earlier examples involve printing output.

While describing optional parameters, I use a good_day() function that prints out a pleasant greeting:
      good_day("Bob");
      // Good day, Bob.
If an optional emphatic parameter is supplied, then the printed message will be a bit stronger:
      good_day("Bob", emphatic: true);
      // Good day, Bob.
      // I said good day!
Dart, of course, has a wonderful syntax to support optional parameters. This makes the definition of the good_day function quite easy:
good_day(name, {emphatic}) {
  print("Good day, ${name}.");
  if (emphatic) {
    print("I said good day!");
  }
}
After a bit of fiddling, I opt to override the built-in print() method. Instead of sending messages to STDOUT (with the SDK) or the console (in the browser), I store them in a private list of all of the messages that were sent to print():
var _prints = [];
print(val) => _prints.add(val);
If I am careful to clear that list before each test, I can test the expected print output against the _prints list. Doing something before each test is the purview of the setUp function, so my tests can be written something like:
    setUp(() => _prints = []);

    test('required only', (){
      good_day("Bob");
      // Good day, Bob.

      expect(_prints, equals(['Good day, Bob.']));
    });
And, thanks to that setUp() which clears the _prints list each time, subsequent tests are also mercifully clean:
    test('optional named parameter', (){
      good_day("Bob", emphatic: true);
      // Good day, Bob.
      // I said good day!

      expect(_prints, equals([
        'Good day, Bob.',
        'I said good day!'
      ]));
    });
The only problem with this approach is the duplication between the comment (that appears in the book to signify the print output) and the expected list of print output. I might try reading the source code from the test, but this seems more trouble than it is worth. The test will be harder to read, which would make it harder to see what is going wrong when the test breaks.

The best solution is likely to simply limit the number of code examples that print output. That may even make some of the discussion in the book better. But, for those examples where print() makes sense, I have a decent working solution.


Day #607

No comments:

Post a Comment