Skip to content
This repository has been archived by the owner on Aug 5, 2021. It is now read-only.

Unit Testing

Owen Buckley edited this page Aug 4, 2018 · 15 revisions

Unit testing is an important part of developing any application. This document details configuration and setup for unit testing using web-component-tester.

⚠️ We could use your help!

If you're interested in some unit testing related tasks, please consider checking out some related issues we love your help with!

Setup

There are a couple steps needed to get started with unit testing.

For the purposes of this guide, we will be setting up Chrome to run in headless mode. This makes it easy to run in continuous integration environments.

Web Component Tester

Web Component Tester was developed by the Polymer team with the goal of providing a test driven runtime and environment. In addition to being a test runner, it also provides Mocha and Chai out of the box with support for both TDD and BDD testing flavors.

Java ☕

WCT use Selenium under the hood, so you will need to make sure that you have a JRE installed and available on your PATH

$ which java
/usr/bin/java
$ java --version
java 10.0.1 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)

If you use Docker, checkout this handy container that has all the essential NodeJS development tools ready out of the box, including Java and Puppeteer!

Install WCT and needed dependencies 📦

# yarn
$ yarn add wct-browser-legacy wct-headless web-component-tester @polymer/test-fixture @webcomponents/webcomponentsjs --dev

# or npm
$ npm install wct-browser-legacy wct-headless web-component-tester @polymer/test-fixture @webcomponents/webcomponentsjs --save-dev

Configure WCT ⚙️

Add this to the root of your project in a file called wct.conf.json.

{
  "plugins": {
    "local": {
      "disabled": true
    },
    "headless": {
      "browsers": [
        "chrome"
      ],
      "browsersOptions": {
        "chrome": [
          "window-size=1920,1080",
          "headless",
          "disable-gpu",
          "no-sandbox"
        ]
      }
    }
  }
}

Create a test! 🔴 🔵

src/greeting.js - our component

import { LitElement, html } from '@polymer/lit-element';

class GreetingComponent extends LitElement {
  
  static get properties() {
    return {
      name: {
        type: String,
        attrName: 'name'
      }
    };
  }

  _render(props) {
    return html`
      <style>
        :host .name {
          color: green;
        }
      </style>
      
      <h1 class="greeting">Hello <span class="name">${props.name}</span>!</h1>
    `;
  }
}

customElements.define('x-greeting', GreetingComponent);

test/index.html Our test scaffold that pulls in polyfills and sets up our component in a fixture for unit testing/

<!doctype html>
<html>

  <head>
    <meta charset="utf-8">
    <script src="../node_modules/wct-browser-legacy/browser.js"></script>
    <script src="../node_modules/@polymer/test-fixture/test-fixture-mocha.js"></script>
    <script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
    <script type="module" src="../src/greeting.js"></script>
    
    <!-- this creates a test fixture for unit test -->
    <test-fixture id="greeting">
      <template>
        <x-greeting name="Owen"></x-greeting>
      </template>
    </test-fixture>
      
    <script>
      WCT.loadSuites([
       './greeting.spec.js'
      ]);
    </script>

  </head>
  
</html>

test/greeting.spec.js This is our unit test file. It will be loaded by our scaffold and will run tests for us.

describe('GreetingComponent', () => {
  const name = 'Owen';
  let componentRoot;
  let greetingContainer;
  let nameContainer;

  beforeEach(() => {
    componentRoot = fixture('greeting').shadowRoot;

    greetingContainer = componentRoot.querySelectorAll('.greeting');
    nameContainer = componentRoot.querySelectorAll('.name');
  });

  it('should have a container element for the greeting', () => {
    expect(greetingContainer.length).to.equal(1);
  });

  it('should have a container element for the name', () => {
    expect(nameContainer.length).to.equal(1);
  });

  it('should display the full greeting in the greeting container element', () => {
    expect(greetingContainer[0].textContent).to.equal(`Hello ${name}!`);
  });

  it('should display just the name attribute in name container element', () => {
    expect(nameContainer[0].textContent).to.equal(name);
  });
});

Run the tests! 🏃

Create an npm script in package.json

"scripts": {
  ...
  "test": "wct --npm --expanded"
}

And use it to run wct from the command line

$ yarn test

Happy testing! 🎉

For a complete working example, check out component-simple-slider.

Clone this wiki locally