The purpose of this overview is to learn the basics of Polymer 1.0 Testing using Mocha, Sinon, and Chai.
Please skip to the Mocha Sinon Chai Cheatsheet to see examples.
Separation of Concerns (the following items are broken up as much as possible for clarity).
Mocha, Sinon, Chai
Web Component Tester
Configuration
HTML Imports
How to Test Things
When to Test With Certain Things
What This Overview Does Not Cover
This Polymer 1.0 Testing overview simply covers the basics of testing using Mocha, Sinon, Chai in relation to Polymer 1.0 web-components.
What You Should Already Know Before Starting
Frequently Asked Question
Quick Summary
Reference
What is Mocha?
Testing framework.
Mocha
What is Sinon?
Test double library for spies, stubs and mocks.
Sinon
What is Chai?
Assertion library.
Chai
What is Jasmine?
Testing framework.
Jasmine
What is the difference between Mocha and Jasmine?
Mocha relies on Sinon for test doubles.
Mocha vs. Jasmine
What is a describe
hook?
Describes the purpose of your test suite.
describe
hook
What is a test suite?
A suite is a test.html file containing describe(s)
Test Suite Example
Why are Mocha arrow lambda functions discouraged?
Lambdas block access to the this.Mocha context.
Avoiding Arrow Lambdas ()=>
What if we are already using lambda functions?
We lose IDE Mocha context help during test development.
More Reason to Avoid Lambdas
What is a beforeEach
hook?
Executes code before every single test.
beforeEach
hook
What is a afterEach
hook?
Executes code after every single test.
afterEach
hook
What is a subject under test (sut)?
Code being tested by a specific test(s)
Subject Under Test
What types of assertions can I make?
assert
or expect
most cases should suffice.
Expect Styles , Assert Styles
How do I run a single suite or test?
describe.only('Some single suite to run'
or it.only(
Run a Single Test
How do I ignore or skip a single test?
xit('Some single test being ignored or skipped',
Skip or Ignore a Single Test
What is a test double?
A test double is also referred to as a stub, mock, spy fake, or dummy.
Test Double
What is a collaborator object?
An object that works with another object to accomplish its goals.
Collaborator Object
What is a sandbox?
A test double wrapper that wraps the entire object.
Sinon Sandboxes
What is web-component-tester?
Browser and CLI web component test runner.
Web Component Tester
What is a test-fixture
?
Creates a web-component sut for testing.
</test-fixture>
template
Test Double Usage Conditions
Test Double
Usage Condition
Sinon Syntax
Dummy
An anonymous stub object for parameter fulfillment.
var
stub = sinon
.stub
();
Fake
When we need to records arguments, values, and exceptions thrown (if any) for collaborators.
var
fake = sinon
.fake
.returns
(
"apple pie
");
Stub
When we need to control a method's behavior from a test to force the code down a specific path.
var
stub = sinon
.stub
(object
,
"method
");
Spy
When the behavior of the spied-on function is not under test, you can use an anonymous function spy.
var
spy = sinon
.spy
(object
,
"method
");
Mock
When we only need to control what a collaborator returns but verify it's input arguments.
var
mock = sinon
.mock
(obj
);
Web Component Tester Configuration File Example
{
"plugins" : {
"local" : {
"browsers" : [
"chrome" ,
"firefox"
] ,
"browserOptions" : {
"chrome" : [
"headless" ,
"disable-gpu" ,
"no-sandbox"
] ,
"firefox" : [
"-headless"
]
}
} ,
"sauce" : {
"disabled" : true ,
"browsers" : [ {
"browserName" : "microsoftedge" ,
"platform" : "Windows 10" ,
"version" : ""
} , {
"browserName" : "internet explorer" ,
"platform" : "Windows 8.1" ,
"version" : "11"
} ,
{
"browserName" : "safari" ,
"platform" : "OS X 10.11" ,
"version" : "9"
}
]
}
}
}
Difference Between a Unit Test and an Integration Test
Unit tests don't need a database or network connection to pass.
Unit Test
Integration Test
The idea behind Unit Testing is to test each part of the program and show that the individual parts are correct.
The idea behind Integration Testing is to combine modules in the application and test as a group to see that they are working fine.
It is kind of White Box Testing.
It is kind of Black Box Testing.
It can be performed at any time.
It usually carried out after Unit Testing and before System Testing.
Unit Testing tests only the functionality of the units themselves and may not catch integration errors, or other system-wide issues.
Integrating testing may detect errors when modules are integrated to build the overall system.
It starts from the module specification.
It starts from the interface specification.
It pays attention to the behavior of single modules.
It pays attention to integration among modules.
Unit test does not verify whether your code works with external dependencies correctly.
Integration tests verifies that your code works with external dependencies correctly.
It is usually executed by developer.
It is usually executed by test team.
Finding errors are easy.
Finding errors are difficult.
Maintenance of unit test is cheap.
Maintenance of integration test is expensive.
Running Tests From the Browser
Run npm run start
Paste the following line in your desired browser to test.
e.g. localhost:8080/test/ci-page-home_test.html
Running Tests From the Command Line
Command
Description
wct --expanded --configFile .\wct.config.json
Runs all tests.
wct --expanded --configFile .\wct.config.json .\test\your-test-file_test.html
Runs specified test class.
wct --expanded --configFile .\wct.config.json --job-name 'My Job Name'
Runs all tests with specified job name.
wct --expanded --configFile .\wct.config.json --job-name 'My Job Name' .\test\your-test-file_test.html
Runs specified test class with specified job name.
wct --help
Web component tester help menu commands.
polymer test
Polymer web component tester command.
polymer --help
Polymer test help menu commands.
Adding a New test.html File
Create your new test file in the project's test folder.
Add the following basic scaffolding minimum content your test file.
Include basic entry test to test the existence of the element.
Make sure your HTML import scripts are as fully qualified as possible (there have been known timing issues otherwise).
../bower_components/webcomponentsjs/webcomponents-lite.js
../bower_components/web-component-tester/browser.js
Ensure you are using functions and not lambdas (Avoiding Arrow Lambdas ()=>
)
<!doctype html>
< html >
< head >
< title > your-test-file test</ title >
< meta charset ="utf-8 ">
< meta name ="viewport " content ="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes ">
< script src ="../bower_components/webcomponentsjs/webcomponents-lite.js "> </ script >
< script src ="../bower_components/web-component-tester/browser.js "> </ script >
< link rel ="import " href ="../your-directory/your-test-file_test.html ">
</ head >
< body >
< test-fixture id ="basic ">
< template >
< your-test-file > </ your-test-file >
</ template >
</ test-fixture >
< script >
describe ( 'your-test-file' , function ( ) {
let _testElement ;
beforeEach ( function ( ) {
_testElement = fixture ( 'basic' ) ;
} ) ;
it ( 'instantiating the element works' , function ( ) {
expect ( _testElement . root ) . to . exist ;
expect ( _testElement . localName ) . to . equal ( 'your-test-file' ) ;
expect ( Polymer . DomModule . import ( _testElement . localName ) ) . to . exist ;
} ) ;
} ) ;
</ script >
</ body >
</ html >
Add the name of your test WCT.loadSuites array.
< script >
WCT . loadSuites ( [
'your-test-file_test.html'
] ) ;
</ script >
Add your additional tests accordingly.
< script >
describe ( 'your-test-file' , function ( ) {
let _testElement ;
beforeEach ( function ( ) {
_testElement = fixture ( 'basic' ) ;
} ) ;
it ( 'instantiating the element works' , function ( ) {
expect ( _testElement . root ) . to . exist ;
expect ( _testElement . localName ) . to . equal ( 'your-test-file' ) ;
expect ( Polymer . DomModule . import ( _testElement . localName ) ) . to . exist ;
} ) ;
describe ( 'someMethod()' , function ( ) {
it ( 'does something' , function ( ) {
} ) ;
it ( 'then does something else' , function ( ) {
} ) ;
} ) ;
} ) ;
</ script >
How Do I Test Multiple Different Browsers Locally?
Set the following key value pairs as System environment variables for your desired installed browsers.
For Windows machine users, see How to set Windows environment variables .
Critical note for Windows users
Make sure all the following values are entered, then move their positions all the way to the top of environment variable path list. Windows will traverse through all environment variables when searching for appropriate key value pair matches. This has been known to take three to five minutes to begin test runs if the environment variables are not immediately found at the top of the environment variable path list. Environment variables can be repositioned when entered as a Path environment variable. This is only necessary when running tests locally via command line when Sauce Labs is disabled.
Only provide the key value pairs for browsers that you actually have installed.
Your path to the installation of course may vary.
Key
Value
LAUNCHPAD_BROWSERS
chrome, edge, firefox, ie, opera
LAUNCHPAD_CHROME
C:\Program Files\Google\Chrome\Application\chrome.exe
LAUNCHPAD_EDGE
C:\Windows\SystemApps\Microsoft.MicrosoftEdge\MicrosoftEdge.exe
LAUNCHPAD_FIREFOX
C:\Program Files\Mozilla Firefox\firefox.exe
LAUNCHPAD_IE
C:\Windows\explorer.exe
LAUNCHPAD_OPERA
C:\Program Files\Opera\00.0.0000.00\opera.exe
For Mac OS/Linux machine users:
Please install your environment variables accordingly.
Mac OS/Linux users don't have to worry about the position(s) of the environment variables.
How to set Windows environment variables
Click Start on the task bar.
For Search programs and fields , enter Environment Variables.
Click Edit the environment variables . This will open the System Properties dialog.
Click Environment Variables . This will open the Environment Variables dialog.
In the System variables section, click New .
This will open the New System Variable dialog.
For Variable name , enter LAUNCHPAD_BROWSERS
.
For Variable value , enter your installed list of browsers (e.g. chrome, edge, firefox, ie, opera).
Click OK.
Repeat 4 - 8 to add the remaining applicable key value pairs.
Acronym
api
Application Programming Interface
bdd
Behavior Driven Development
cli
Command Line Interface
cmd
Command
dev
Development
html
Hypertext Markup Language
ide
Integrated Development Environment
js
JavaScript
npm
Node Package Manager
sut
Subject Under Test
tdd
Test Driven Development
ui
User Interface
url
Universal Resource Locator
vscode
Visual Studio Code
wct
Web Component Tester