The A-Frame codebase aims for as much unit test coverage as possible. Tests give us confidence that changes work and that they do not unexpectedly regress other parts of the code.
Pull requests changing code behavior will usually be asked to accompany unit tests. Bug fixes will also usually be asked to provide unit tests to prevent future regressions.
Unit tests use:
npm run test
to run karma on the command line.assert.equal(value, 5)
).Run npm run test
to run the entire test suite. This starts a watcher. Every change to the codebase will automatically trigger the tests. This is useful in that we don't have to re-run a command every time we want to run the tests.
If we wish to only run a single test suite or a single test case, we can add either set the TEST_FILE
environment variable pattern. This will match for files containing the pattern.
TEST_FILE=geometry npm run test
Or add .only
to the suite or test we wish to run. For example:
// To run just this suite, change: suite('lorum ipsum', function () { // ... }); // to... suite.only('lorum ipsum', function () { // ... }); // To run just this test, change: test('lorem ipsum', function () { // ... }); // to... test.only('lorem ipsum', function () { // ... });
To run only on a specific browser:
npm run test:chrome TEST_FILE=scene npm run test:firefox
The most useful thing to do is read the existing tests and mimic their structure and style.
Tests are structured with each module, component, or custom element getting their own test suite. Methods or features are inner suites within their respective module, component, or custom element. And then test cases go within those inner suites:
suite('module/component/custom element', function () { /** * `setup` hook is run before every test. */ setup(function (done) { done(); // If asynchrony is involved, use `done` to tell when finished. }); suite('method/feature', function () [ /** * A synchronous test case. No need to specify `done`. */ test('does this', function () { assert.equal(1, 1); }); /** * An asynchronous test case. */ test('does that', function (done) { process.nextTick(function () { assert.notEqual(1, 2); done(); // Use `done` to tell when finished in asynchronous test. }); }); }); });
helpers.js:entityFactory
is common called in setup
hooks to setup an entity within a scene that is attached to the body.<a-entity>
, we often to have wait until it fires the 'loaded' event.process.nextTick
after doing DOM manipulations. However, we will not need to do this after Entity.setAttribute
as we have made that synchronous.