- Purpose of This Overview
- What This Overview Does Not Cover
- What You Should Already Know Before Starting
- Crash Course Overview
- Acronyms
- Resources
- 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
This Polymer 1.0 Testing overview simply covers the basics of testing using Mocha, Sinon, Chai in relation to Polymer 1.0 web-components.
- Remote cloud testing services (e.g. Sauce Labs)
- Selenium automation (e.g. Cross browser testing)
- Appium automation (e.g. Mobile device testing)
- Continuous testing (e.g. Karma, Travis CI)
- Continuous inspection (e.g. SonarQube)
- Automation test services (e.g. TestCraft, Leapwork)
- Please see the internal Maritz Sauce Labs Orientation for more information on test automation.
- Extensive Web Component Tester Configuration
- Shady DOM & Shadow Dom Web Component Query Parameters Polymer Polyfill Settings
- Extensive Debugging Techniques
- Open Web Components open-wc
- This looks really interesting and worth looking into for a robust library of web component test helpers.
- However, some of the great things here may only be applicable to Polymer 3.0 or JS imports.
- open-wc Example Tests
-
This overview presumes you have a basic understanding of the following
- bower package management
- npm package management
- Plain JavaScript
- Polymer 1.0
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 |
Frequently Asked Question | Examples | Reference |
---|---|---|
What is the difference between a unit test and integration test? | Difference Between a Unit Test and an Integration Test | What Is the Difference Between a Unit Test and Integration Test? |
What are the differences between a stub, mock, spy, fake, and dummy? | Test Double Usage Conditions | Test Double Differences |
How do I apply argument matching? | Mocha Sinon Chai Cheatsheet | Sinon Argument Matchers |
How do I test an asynchronous method? | Mocha Sinon Chai Cheatsheet | Mocha Asynchronous Testing |
How do I test promises? | Mocha Sinon Chai Cheatsheet | Mocha Promise Testing (resolve, reject) |
How do I mock an API call? | Mocha Sinon Chai Cheatsheet | Sinon Request Fakes |
How do I test the order of method calls? | Mocha Sinon Chai Cheatsheet | Sinon Assertions (Asserting Call Order) |
How do I manipulate a callback function? | Mocha Sinon Chai Cheatsheet | Sinon Replacing Callback Functions |
What is the wct.config.json file? |
wct.config.json File Example |
WCT Config Documentation |
How do I run tests in the browser? | Running Tests From the Browser | Polymer 1.0 Documentation |
How do I run tests from the command-line? | Running Tests From the Command Line | Same As Running Tests From the Browser |
How do I debug tests? | Same As Running Tests From the Browser | By running tests in the browser (Polymer 1.0). |
How do I add a new HTML test file? | Adding a New test.html File | Loading Suites WCT.loadSuites([]); |
How do I test multiple different browsers locally? | How Do I Test Multiple Different Browsers Locally? | Launch Pad Resource |
Are there any Polymer online community site(s)? | Resources section for additional information. | Polymer Slack Channel is an excellent Polymer community resource. |
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 ); |
{
"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"
}
]
}
}
}
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. |
- Run
npm run start
- Paste the following line in your desired browser to test.
- e.g.
localhost:8080/test/ci-page-home_test.html
- e.g.
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. |
- 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>
-
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 - Critical note for Windows users
-
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.
- 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 |
Name | Resource |
---|---|
Appium automation | Mobile device testing |
Are there any Polymer online community site(s)? | Polymer Slack Channel is an excellent Polymer community resource. |
Automation test services | TestCraft, Leapwork |
Chai | Chai |
Continuous testing | Karma, Travis CI |
How do I add a new HTML test file? | Loading Suites WCT.loadSuites([]); |
How do I apply argument matching? | Sinon Argument Matchers |
How do I ignore or skip a single test? | Skip or Ignore a Single Test |
How do I manipulate a callback function? | Sinon Replacing Callback Functions |
How do I mock an API call? | Sinon Request Fakes |
How do I run a single suite or test? | Run a Single Test |
How do I run tests in the browser? | Polymer 1.0 Documentation |
How do I test an asynchronous method? | Mocha Asynchronous Testing |
How do I test multiple different browsers locally? | Launch Pad Resource |
How do I test promises? | Mocha Promise Testing (resolve, reject) |
How do I test the order of method calls? | Sinon Assertions (Asserting Call Order) |
Jasmine | Jasmine |
Maritz Sauce Labs Orientation | Sauce Labs Orientation |
Mocha | Mocha |
Mocha Sinon Chai Cheatsheet | Mocha Sinon Chai Cheatsheet |
Open Web Components | Robust Web Component Test Resources |
Open Web Components Test Examples | Open Web Component Test Examples |
Polymer 1.0 Library | Polymer 1.0 Library |
Polymer Project | Polymer Project |
Remote cloud testing services | Sauce Labs |
Selenium automation | Cross browser testing |
Shady DOM & Shadow Dom Web Component Query Parameters | Polymer Polyfill Settings |
Sinon | Sinon |
What are the differences between a stub, mock, spy, fake, and dummy? | Test Double Differences |
What if we are already using lambda functions? | More Reason to Avoid Lambdas |
What is a afterEach hook? |
afterEach hook |
What is a beforeEach hook? |
beforeEach hook |
What is a describe hook? |
describe hook |
What is a test-fixture ? |
</test-fixture> template |
What is a collaborator object? | Collaborator Object |
What is a sandbox? | Sinon Sandboxes |
What is a subject under test (sut)? | Subject Under Test |
What is a test double? | Test Double |
What is a test suite? | Test Suite Example |
What is the wct.config.json file? |
WCT Config Documentation |
What is the difference between a unit test and integration test? | What Is the Difference Between a Unit Test and Integration Test? |
What is the difference between Mocha and Jasmine? | Mocha vs. Jasmine |
What is web-component-tester? | Web Component Tester |
What types of assertions can I make? | Expect Styles, Assert Styles |
Why are Mocha arrow lambda functions discouraged? | Avoiding Arrow Lambdas ()=> |