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 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 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 Helpers 2

PolarGridHelper The PolarGridHelper is an object to define polar grids. Grids are two-dimensional arrays of lines. Code Example const radius = 10; const radials = 16; const circles = 8; const divisions = 64; const helper =...

4 minutes read.

ThreeJS Loaders 2

ImageBitmapLoader A loader that converts an image to an ImageBitmap. An ImageBitmap provides an asynchronous and resource-efficient path for preparing textures for WebGL rendering. ImageBitmapLoader, unlike FileLoader, does not prevent multiple concurrent...

8 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 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 Animation Systems

You may animate many aspects of your models with the three.js animation system, including the bones of a skinned and rigged model, morph targets, multiple material properties (colours, opacity, booleans),...

3 minutes read.

ThreeJS Loading 3D Models

There are hundreds of file formats for 3D models, each with its own purpose, set of features, and level of complexity. Although three.js has a lot of loaders, choosing the...

2 minutes read.

ThreeJS AnimationClip

An AnimationClip is a group of keyframe tracks that may be reused to depict an animation. The "Animation System" page in the "Next Steps" part of the handbook provides an overview...

2 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 Installation

You can use npm and modern build tools to install three.js, or you can get started quickly with static hosting or a CDN. Installing from npm is the best option...

4 minutes read.

ThreeJS BufferAttribute

This class stores data for an attribute associated with a BufferGeometry (such as vertex positions, face indices, normals, colours, UVs, and any custom attributes), allowing for more efficient data passing...

4 minutes read.

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 Materials 3

RawShaderMaterial This class works just like ShaderMaterial, except that definitions of built-in uniforms and attributes are not automatically prepended to the GLSL shader code. Code Example const material = new THREE.RawShaderMaterial( {    ...

9 minutes read.

ThreeJS AnimationObjectGroup and Utils

AnimationObjectGroup A group of objects that receives a shared animation state. Usage Add items you'd normally send as 'root' to AnimationMixer's function Object() { [native code] } or clipAction method, and instead pass...

2 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.

ThreeJS AnimationMixer

The AnimationMixer is a player that allows you to play animations on a specific object in the scene. When many items in a scene are animated individually, each object may...

2 minutes read.

ThreeJS Scenes

Fog This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance. Constructor Fog( color : Integer, near : Float, far : Float ) The color parameter is...

3 minutes read.

ThreeJS Audio

It is used to create a non-positional (global ) audio object. Code Example: // create an AudioListener and add it to the camera const listener = new THREE.AudioListener(); camera.add( listener ); // create a global...

6 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.