Polymer Unit Testing


In the front-end world, testing is a weird topic. Developers know how much testing is important, but lots of them don’t embrace this practice. This is because testing is often perceived as a time consuming and a difficult task.

Sometimes the harder part is just getting started, and this is not only specific to testing. For this reason, in this article we will go through the basics, leaving more advanced topics and some details out. Once you have grasped the core concepts and got your first tests working, I bet you’ll be more motivated to dig deeper into the topic.


Web component tester

Polymer comes with an handy tool called web-component-tester (WCT), that will make testing your elements really easy.

If you are used to test your applications, your first thought is that you don’t want to learn a new tool, right? The good news is that you probably already know the tools WCT is built on. If you are already familiar with Mocha, Chai and Sinon, you are good to go.
If you are new to testing and you never heard those names before, don’t worry and keep reading.

Setup

First, you need to install WCT via NPM globally.

npm install -g web-component-tester

As a test suite you can use an .html file like the following:

The basic HTML page with the required dependencies

As you can see, your test suite looks almost the same as the HTML file you normally use to contain your Polymer elements. The only difference is you need to include browser.js, that is in charge of loading all the required libraries for you, and test-fixture-mocha.js of which I’ll talk in a moment.

Writing a test

In this article you will test a Polymer element called <flip-clock>.

Check out the <flip-clock> source code on Github clicking on the image

The first thing you need to do, is to import the <flip-clock> element into the page. Along with it, import the <test-fixture> element as well.

The <test-fixture> element can simplify the exercise of consistently resetting a test suite’s DOM. To use it, wrap the test suite’s DOM as a template.
You’ll find out later why it is crucial for this test.
Elements import and instantiation

You are ready to write the actual test.

Add inside a script tag the describe function with the element’s name under test, in this case <flip-clock>. In the beforeEach function we reference our element with its id. As you probably imagine, this function is called before each test.
The context function is not mandatory, but it is a convenient way to group up our tests.

describe('<flip-clock>', function() {
var clock;

beforeEach(function() {
clock = fixture('clock');
});
  context('common tests', function() {

});
});

The element exposes the showButtons property and its default value is false. When it’s true, the command buttons show up. In order to toggle their visibility, you need to add the show-button attribute on your custom element.

First, set the show-buttons attribute on the element, then make sure the showButtons property is true. After that, check if the buttons, contained in a div with the buttons class, are actually visible.

Since WCT uses Mocha and Chai, you can choose between all the interfaces those libraries provide. I personally like the Chai’s BDD style with the expect interface, but you can choose the one you like the most.
it('should display the command buttons', function() {
clock.setAttribute('show-buttons', 'true');
expect(clock.showButtons).to.be.equal(true);
expect(clock.querySelector('.buttons').attributes)
.to.have.ownProperty('visible');
});

Now repeat the test without setting the show-buttons attribute. In this case we expect the showButtons property to be false and the buttons are not visible.

it('should not display the command buttons', function() {
expect(clock.showButtons).to.be.equal(false);
expect(clock.querySelector('.buttons').attributes)
.to.not.have.ownProperty('visible');
});

You’ll end up with this code:

The final result

Running a test

To do that, open a terminal in the element’s root directory and launch the web component tester with the wct command. It will automatically run the tests in all the browsers installed on your machine.

Wow, your first two tests just passed! But, What would have happened if you have had not used the <test-fixture> element? The short answer is: the second test would fail.
This because you set the show-buttons attribute to true and, in the following test, you expect showButtons to be false.
With <text-fixture> (and the beforeEach function) you will run every test on a “clean” element.

What next?

Take a look at the <flip-clock> project on Github to learn more on how this element is built and to check out the other tests I wrote for this element.
You can find more information about <test-fixture> on its repository.

The web-component-tester README.md is also a great resource to get started.