Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

A Guide to Set Up UI Test Framework

DZone's Guide to

A Guide to Set Up UI Test Framework

UIs are increasingly becoming an important part of a web dev's role. We go over how to make a UI using a particular tech stack.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

Background

As web apps become more and more complex, UI tests become more and more important. But how is one supposed to set up a test framework for front-end code? Those who have done such jobs may know that there are many challenges to making the front-end tests meet the real world's needs. The biggest challenges are following two aspects:

  1. We need to deal with the DOM operations in the UI tests. The DOM operation is essentially very complex and heavy. We can bypass it when writing UI test cases.

  2. We need to deal with asynchronous operations from here to there in the UI tests. The async operations include Ajax requests, timer(setTimeout), UI Animation, etc.

At my company, LogicMonitor, we previously used Phantom.js + Blanket + Mocha + Chai to set up a UI test framework, but we found the following drawbacks:

  1. Phantom is mainly used to resolve problem #1, i.e. DOM operations. But we know Phantom.js is not the real browser that people are using daily. So there may be some cases where the test case can pass in Phantom.js, but can't pass in Chrome or other real browsers.

  2. It's hard to change the browser from Phantom.js to another. If we want to, it usually means a framework-level change.

  3. When there are a lot of test cases, test running will become very slow.     

Then, we found Google released ChromeHeadless with Chrome 59. It's a killer feature, because "It's a way to run the Chrome browser in a headless environment. Essentially, running Chrome without chrome! It brings all modern web platform features provided by Chromium and the Blink rendering engine to the command line."[1].  It means we can run our test cases in real Chrome using the command line!

But can we use Chrome Headless in real products? After some investigation, we found Karma is a very nice way to meet our requirements. First, it has been well designed for different browsers. In Karma, it's very easy to switch from one browser to another browser (including Phantom.js). Second, there are many plugins for Karma, for example, karma-mocha, karma-jasmine, karma-requirejs, etc.; it can save us lot of time for many common tasks. Third but not the last, it supports the AMD module (RequireJS) very well, actually, the Karma wizard has an option for RequireJS.

Unfortunately, there are few tutorials for configuring Karma + Chrome Headless + Mocha + Chai + RequireJS. Among the limited resources, some are wrong/misleading. So here, I wrote this guide to introduce how to setup UI test frameworks using Karma + Chrome Headless + Mocha + Chai + RequireJS. There are many useful caveats that other tutorials may not include.

Technical Stack

Karma (Test Runner)

https://karma-runner.github.io/1.0/index.html

Chrome Headless (Browser platform)

Mocha (Test Framework)

http://mochajs.org/

Chai (Assertion Library)

http://chaijs.com/

RequireJS (AMD module management)

http://requirejs.org/

Step-by-Step Guide

Step 1: Install Dependencies

In your UI project directory, run the following commands to install dependencies:

npm install --save-dev karma karma-chrome-launcher karma-mocha karma-chai
npm install --save-dev mocha chai
npm install --save requirejs

Step 2: Generate karma.conf.js and test-main.js

Note, some tutorials write "karma.config.js," but it's not standard or current Karma version. For the current version, the default config file for Karma should be named "karma.conf.js."

You can manually create "karma.conf.js" if you're very familiar with the configuration options, or I suggest you create it using the Karma command line wizard. You can use the following command to begin the Karma configuration initialization:

./node_modules/karma/bin/karma init

After you run the above command, you will be prompted with some questions. Here is a review:

Q1. Which testing framework do you want to use?

Mocha

Q2. Do you want to use RequireJS?

Yes

Q3. Do you want to capture any browsers automatically?

Chrome

Q4. What is the location of your source and test files?

Input the file patterns for your source and test files.

One GLOB pattern per line.

Q5 Should any of the files included by the previous patterns be excluded?

Exclude files.

Q6. Do you want to generate a bootstrap file for RequireJS?

Yes

Q7. Do you want Karma to watch all the files and run the tests on change?

Yes

After the wizard, Karma will generate "karma.conf.js" and "test-main.js" automatically for you.

Step 3: Change the karma.conf.js

You may need to check and adjust the following options:

1. Change Frameworks

We will use Chai as the assertion lib. 

Please change 

frameworks: ['mocha', 'requirejs']

to

frameworks: ['mocha', 'requirejs', 'chai']

Also note here that the order matters: the 'chai' should be put after 'requirejs' or you will be prompted with following errors:

Uncaught TypeError: Cannot read property 'should' of undefined at node_modules/karma-chai/adapter.js:4

2. Check Files Config

Make sure the files config is correct. Be careful if you have hidden files (or called dot files) as these need to be included in the files - you must specify the dot file pattern independently. Because Karma uses node-glob for file pattern matching, if you want to include the hidden files in your Karma tests, please note the illustration about dot files:

If a file or directory path portion has a  . as the first character, then it will not match any glob pattern unless that pattern's corresponding path part also has a  . as its first character.

For example, the pattern a/.*/c would match the file at a/.b/c. However, the pattern a/*/c would not, because *does not start with a dot character.

Here is a real world config for the hidden files:

{pattern: 'dashboard/**/*.js', included: false},
{pattern: 'dashboard/**/.*.js', included: false}, // including the hidden files

3. Check Browsers Config

The wizard generates:

browsers: ['Chrome']

To use Chrome Headless, you can change the config to:

browsers: ['ChromeHeadless']

See, it's so simple for Karma to change the browser! 

Step 4: Change the test-main.js

If you have used a RequireJS config before, you can copy your config into test-main.js, and then make sure the following three options are correct:

baseUrl: '/base',   // Because karma serve files using a '/base/xxx' path
deps: allTestFiles,
callback: window.__karma__.start

Because Karma serves files using a '/base/' prefix, you need to config your RequireJS baseUrl to '/base'. The docs specify the Test Files you want to load before Karma starts to execute. The callback is to let the Browser start Karma after the RequireJS loads all dependencies.

Demo Code

Please visit here for the demo code.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
karma ,requirejs ,mocha ,ui testing ,web dev

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}