ThreeJS Testing with npm

This article explains how to install three.js in a node.js environment so that automated tests may be run. Tests can be done manually or with the help of automated CI technologies like Travis.

The short version

If you're comfortable with node and npm,

$ npm install three --save-dev

and add

const THREE = require('three');

to your test.

Create a testable project from scratch

Here's a quick rundown of these tools if you're not familiar with them (for linux, the installation process will be slightly different using windows, but the NPM commands are identical).

Basic setup

Install npm and nodejs. The shortest path typically looks something like

$ sudo apt-get install -y npm nodejs-legacy
# fix any problems with SSL in the default registry URL
$ npm config set registry http://registry.npmjs.org/

Make a new project directory

$ mkdir test-example; cd test-example

Ask npm to create a new project file for you:

$ npm init

and accept all defaults by hitting Enter on all the prompts. This will create package.json.

Try and start the test feature with

$ npm test

This will fail, which is expected. If you look in the package.json, the definition of the test script is

"test": "echo \"Error: no test specified\" && exit 1"

Add mocha

We're going to use mocha.

Install mocha with

$ npm install mocha --save-dev

You'll notice that node modules/ have been created, and your dependencies have been added to them. Also, your package.json file has been updated: —save-dev is used to add and update the property devDependencies.

To use mocha for testing, edit package.json. We only want to execute mocha and specify a verbose reporter when test is called. By default, this will run everything in test/ (npm ERR! if test/ does not exist; make it with mkdir test).

"test": "mocha --reporter list"

Rerun the test with

$ npm test

This should now succeed, reporting 0 passing (1ms) or similar.

Add three.js

Let's pull in our three.js dependency with

$ npm install three --save-dev

If you need a different three version, use

$ npm show three versions

to see what's available. To tell npm the right one, use

$ npm install three@0.84.0 --save

(0.84.0 in this example). --save makes this a dependency of this project, rather than dev dependency.

Mocha will look for tests in test/, so let's

$ mkdir test

Finally, we actually need a JS test to run. Let's add a simple test that will verify that the three.js object is available and working. Create test/verify-three.js containing:

const THREE = require('three');
const assert = require('assert');


describe('The THREE object', function() {
  it('should have a defined BasicShadowMap constant', function() {
    assert.notEqual('undefined', THREE.BasicShadowMap);
  }),


  it('should be able to construct a Vector3 with default of x=0', function() {
    const vec3 = new THREE.Vector3();
    assert.equal(0, vec3.x);
  })
})

Finally let's test again with $ npm test. This should run the tests above and succeed, showing something like:

The THREE object should have a defined BasicShadowMap constant: 0ms
The THREE object should be able to construct a Vector3 with default of x=0: 0ms
2 passing (8ms)

Add Your Own Code

There are three things you must do:

  • Create a test for your code's expected behaviour and save it under test/. Here's a real-life project sample.
  • For use with need, export your functional code in such a way that nodejs can view it. It can be found here.
  • In the same way that we did a require('three') in the example before, require your code into the test file.

Depending on how you manage your code, items 2 and 3 may differ. The export part is exactly at the end of the Physics.js example above. The module is given an object. exports:

//=============================================================================
// make available in nodejs
//=============================================================================
if (typeof exports !== 'undefined')
{
  module.exports = Physics;
}

Dealing WIth Dependencies

Skip this section if you're already using something clever like require.js or browserify.

In most cases, a three.js project will execute in the browser. As a result, the browser loads modules by executing a series of script tags. Dependencies aren't an issue for your individual files. However, because there is no index.html to connect things together in a nodejs context, you must be explicit.

You'll need to tell the node to load other files if you're exporting a module that depends on them. Here's one method:

  1. Check to see if you're in a nodejs environment at the start of your module.
  2. Declare your dependencies explicitly if this is the case.
  3. If you're not in a browser, there's no need to do anything else.

Example code from Physics.js:

//=============================================================================
// setup for server-side testing
//=============================================================================
if (typeof require === 'function') // test for nodejs environment
{
  const THREE = require('three');
  const MY3 = require('./MY3.js');
}

Related Topics

ThreeJS Creating VR Content

This article gives a quick introduction of the main components of a three.js-based web-based VR application. Workflow      First, you have to include VRButton.js into your project. import { VRButton } from...

1 minute read.

ThreeJS Updating Things

If an item has been added to the scene with the specified code, it will immediately update its matrices. const object = new THREE.Object3D(); scene.add( object ); or, if they are the child...

4 minutes read.

ThreeJS Lines and Texts

Drawing Lines Let's say you want to draw a line or a circle, not a wireframe Mesh. First, we need to set up the renderer, scene, and camera. Here is the...

3 minutes read.

ThreeJS Keyframe Tracks and Animation

A KeyframeTrack is a timed series of keyframes that are made up of lists of times and related values and are used to animate an object's unique property. BooleanKeyframeTrack A Track of...

3 minutes read.

ThreeJS Raycaster

This class is intended to help with raycasting. Raycasting is used for a variety of purposes, including mouse picking (determining which objects in 3D space the mouse is over). Code Example const...

4 minutes read.

ThreeJS InterleavedBuffer

The term "interleaved" refers to the packing of multiple attributes, possibly of different types (e.g., position, normal, uv, colour) into a single array buffer. Constructor InterleavedBuffer( array : TypedArray, stride : Integer...

3 minutes read.

ThreeJS Shadows

LightShadow Serves as a base class for the other shadow classes. Constructor LightShadow( camera : Camera ) camera - the light's view of the world. Create a new LightShadow. This is not intended to be...

7 minutes read.

ThreeJS Material - Mesh

MeshBasicMaterial A material for drawing geometries in a simple shaded (flat or wireframe) way. This material is not affected by lights. Constructor MeshBasicMaterial( parameters : Object ) parameters - (optional) an object with one or...

24 minutes read.

ThreeJS Material

Abstract base class for materials. Materials describe the appearance of objects. They are defined in a (mostly) renderer-independent way, so you don't have to rewrite materials if you decide to use...

6 minutes read.

ThreeJS Objects

Bone A bone that is part of a Skeleton. The skeleton in turn is used by the SkinnedMesh. Bones are almost identical to a blank Object3D. Code Example const root = new THREE.Bone(); const...

12 minutes read.

ThreeJS Math

Box2 Represents an axis-aligned bounding box (AABB) in 2D space. Constructor Box2( min : Vector2, max : Vector2 ) min - (optional) Vector2 representing the lower (x, y) boundary of the box. Default is...

48 minutes read.

ThreeJS Geometries-1

BoxGeometry BoxGeometry is a geometry class for a rectangular cuboid with a given 'width', 'height', and 'depth'. On creation, the cuboid is centered on the origin, with each edge parallel to...

7 minutes read.

ThreeJS Compatibiliy Check and Running Locally

Even though this is becoming less of an issue, some devices or browsers may still be incompatible with WebGL. The method below enables you to check if it is supported...

3 minutes read.

ThreeJs Tutorial

What is Three.JS? Three.js is a cross-browser JavaScript library and application programming interface that uses WebGL to create and display animated 3D computer graphics in a web browser. The source code...

6 minutes read.

ThreeJS Testing with npm

This article explains how to install three.js in a node.js environment so that automated tests may be run. Tests can be done manually or with the help of automated CI...

4 minutes read.

ThreeJS Disposing an Object

The disposal of unwanted library entities is a crucial component of improving performance and avoiding memory leaks in your programme. When you create a three.js type instance, you set aside...

4 minutes read.

ThreeJS Managers

DefaultLoadingManager When no custom manager is specified, most loaders use a global instance of the LoadingManager. This will suffice for most purposes, but there may be times when you want separate loading...

4 minutes read.

ThreeJS Renderers

WebGLMultipleRenderTargets A special render target that enables a fragment shader to write to several textures. This approach is useful for advanced rendering techniques like post-processing or deferred rendering. Heads up: WebGLMultipleRenderTargets...

15 minutes read.

ThreeJS Cameras

ArrayCamera ArrayCamera can be used to render a scene using a preset group of cameras quickly. This is an important feature of VR scene rendering performance. An array of sub cameras is...

6 minutes read.

ThreeJS Keyframe Track

A KeyframeTrack is a timed series of keyframes that are made up of lists of times and related values and are used to animate an object's unique property. The "Animation System"...

4 minutes read.