Thursday, August 28, 2014

Getting Started with Polymer-Test-Tools


I can whine for long periods of time about how much better Dart testing is than JavaScript. Loooong periods. But let's face it, that is hardly constructive and, worse, it ignores the hard work of talented folks that are working to make things better.

Last night, I added some simple Dart tests to one of the chapters in Patterns in Polymer. The primary element in that chapter (both the Dart and JavaScript versions of the book) is <click-sink> which, when embedded in another element, will report on events in the containing element. The Dart tests were easy to add, so tonight I do the same in JavaScript.

Until now, my testing solution for JavaScript Polymer has been Karma and Jasmine. It takes a little more work to get these tests working: package.json to install Karma dependencies via NPM, bower.json to install Polymer dependencies via Bower, Jasmine setup for Polymer, etc. In all honesty, it's not that much harder to setup than in Dart.

I would note that the tests just are not as pretty:
  beforeEach(function(done){
    el = document.querySelector('click-sink');
    setTimeout(done, 0); // One event loop for elements to register in Polymer
  });

  describe('element content', function(){
    beforeEach(function(done){
      document.body.click();
      setTimeout(done, 0); // One event loop for Polymer to process
    });
    it('displays click events', function(){
      expect(el.shadowRoot.textContent).toContain('Page clicked');
    });
  });
I really am partial to scheduled_test's schedules:
  test('displays click events', (){
    var el = query('click-sink');
    schedule(()=> document.body.click());
    schedule(() {
      expect(el.shadowRoot.text, contains('Page clicked'));
    });
  });
But I'm not whining!

Instead, I went in search of some other examples of Polymer testing in JavaScript and stumbled across polymer-test-tools, which is a project from the Polymer team itself that has “common tools for testing Polymer elements.” It uses Karma, but instead of Jasmine, it uses Mocha and Chai. I have already investigated both as testing solutions. I remain open to the switch, so let's see if polymer-test-tools can convince me.

It is non-obvious how to use polymer-test-tools, but it has a bower.json, suggesting that I need to add it to my bower.json development dependencies:
$ bower install -D "Polymer/polymer-test-tools"
...
polymer-test-tools#0.4.0 bower_components/polymer-test-tools
Next, I update my karma.conf.js file to pull in the settings from polymer-test-tools:
module.exports = function(config) {
  var common = require('./bower_components/polymer-test-tools/karma-common.conf.js');

  config.set(common.mixin_common_opts(config, {
    // Override with my setting here...
  }));
};
I retain some of my own settings—especially the list of the test files—but remove most of what is listed in the common karma configuration. But when I run this, I get warnings about plugins that are not installed:
$ karma start --single-run
WARN [plugin]: Cannot find plugin "karma-mocha".
  Did you forget to install it ?
  npm install karma-mocha --save-dev
WARN [plugin]: Cannot find plugin "karma-browserstack-launcher".
  Did you forget to install it ?
  npm install karma-browserstack-launcher --save-dev
WARN [plugin]: Cannot find plugin "karma-ie-launcher".
  Did you forget to install it ?
  npm install karma-ie-launcher --save-dev
WARN [plugin]: Cannot find plugin "karma-ios-launcher".
  Did you forget to install it ?
  npm install karma-ios-launcher --save-dev
WARN [plugin]: Cannot find plugin "karma-safari-launcher".
  Did you forget to install it ?
  npm install karma-safari-launcher --save-dev
WARN [plugin]: Cannot find plugin "karma-crbot-reporter".
  Did you forget to install it ?
  npm install karma-crbot-reporter --save-dev
I have no desire for most of those, so I override them in my settings:
module.exports = function(config) {
  var common = require('./bower_components/polymer-test-tools/karma-common.conf.js');

  config.set(common.mixin_common_opts(config, {
    // ...
    plugins: [
      'karma-mocha',
      'karma-chrome-launcher',
      'karma-script-launcher'
    ]
  }));
};
That still complains about a lack of karma-mocha:
$ karma start --single-run
WARN [plugin]: Cannot find plugin "karma-mocha".
  Did you forget to install it ?
  npm install karma-mocha --save-dev
I had hoped to get this automatically from polymer-test-tools since it includes both mocha and chai:
$ ls bower_components/polymer-test-tools/     
bower.json  chai  htmltest.js  karma-common.conf.js  mocha  mocha-htmltest.js  README.md  tools.html
Alas, this is not the case.

After following the instructions (npm install karma-mocha --save-dev), I run into another problem:
$ karma start
INFO [karma]: Karma v0.12.23 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
ERROR [karma]: [Error: error:24064064:random number generator:SSLEAY_RAND_BYTES:PRNG not seeded]
Error: error:24064064:random number generator:SSLEAY_RAND_BYTES:PRNG not seeded
    at Manager.generateId (/home/chris/repos/polymer-book/book/code-js/parent_events/node_modules/karma/node_modules/socket.io/lib/manager.js:750:12)
    at /home/chris/repos/polymer-book/book/code-js/parent_events/node_modules/karma/node_modules/socket.io/lib/manager.js:805:21
    at Manager.authorize (/home/chris/repos/polymer-book/book/code-js/parent_events/node_modules/karma/node_modules/socket.io/lib/manager.js:931:5)
    at Manager.handleHandshake (/home/chris/repos/polymer-book/book/code-js/parent_events/node_modules/karma/node_modules/socket.io/lib/manager.js:801:8)
    at Manager.handleRequest (/home/chris/repos/polymer-book/book/code-js/parent_events/node_modules/karma/node_modules/socket.io/lib/manager.js:616:12)
    at Server.<anonymous> (/home/chris/repos/polymer-book/book/code-js/parent_events/node_modules/karma/node_modules/socket.io/lib/manager.js:119:10)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2076:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:120:23)
    at Socket.socket.ondata (http.js:1966:22)
Yikes. Apparently, this is a known issue with Karma. Unfortunately, it looks like I need to install a new node.js. Sigh.

I will call it a night here and maybe pick back up with this tomorrow. While working through this, I am starting to get the feeling that polymer-test-tools is not a general purpose Polymer testing helper. It seems like it helps quite a bit with testing Polymer internals like Shadow DOM, but it may not be appropriate for coders building and maintaining their own Polymer elements. Even so, I may pick back up with this if, for no other reason, than to learn a little from the smart folks behind Polymer.


Day #166

No comments:

Post a Comment