Bedrock Test Framework
raw JSON →bedrock-test is a JavaScript testing utility for the Bedrock modular web application framework. It provides a structured approach for setting up and running tests, leveraging Mocha for backend unit tests and Karma (formerly Protractor, updated in search results to Karma) for frontend testing. The package, currently at version 6.1.0, is part of the Digital Bazaar Bedrock ecosystem, indicating its release cadence is likely tied to the development of the main Bedrock framework. Key differentiators include its ability to create self-contained test environments for individual modules, manage configuration overrides (e.g., `config.test.js` overriding `config.js`), and facilitate the inclusion of helper functions and mock data for comprehensive testing scenarios. It aims to simplify complex testing setups within the Bedrock architecture by defining how test files are loaded and executed, supporting a modular and independent testing approach for Bedrock-based projects.
Common errors
error Error: Cannot find module 'bedrock-test' ↓
bedrock-test is listed in your package.json and run npm install (or yarn add bedrock-test). Verify that the module resolution path is correct if using custom configurations. error ReferenceError: bedrock is not defined ↓
require('@bedrock/core') or import '@bedrock/core'; is executed early in your test setup process, typically in the main test.js file, before bedrock-test is loaded. bedrock.start() should also be called. error Mocha tests are not running or only a subset of tests are executing. ↓
config.mocha.tests correctly pushes the directories or specific file paths where your Mocha test files (.js) are located. Ensure the paths are absolute and correct, especially when using path.join and __dirname. error TypeError: Cannot read properties of undefined (reading 'on') for bedrock.events ↓
import * as bedrock from '@bedrock/core'; is at the top of your main test file and that any event subscriptions for bedrock.events occur after bedrock has been fully loaded. Consider await bedrock.start() to ensure the framework is ready. Warnings
breaking The Bedrock framework (and by extension `bedrock-test`) updated its Node.js requirement to v10.12.0 in `bedrock@3.0.0`, and later to `>=8` in `bedrock@1.18.0` due to async/await usage. Ensure your environment meets these minimums, as older Node.js versions will cause failures. ↓
breaking As of `bedrock@3.0.0`, `bedrock.start()` now returns a Promise instead of using a callback. Code relying on the callback pattern for `bedrock.start()` must be updated to use `async/await` or `.then/.catch` for proper asynchronous handling. ↓
breaking The core `bedrock` framework removed its internal Mocha unit test framework in `bedrock@2.0.0`, relocating all testing functionality entirely to the `bedrock-test` module at version `bedrock-test@4`. Direct usage of internal `bedrock` testing utilities is no longer supported. ↓
gotcha When configuring tests, `config.test.js` files are loaded after `config.js` files. This means that any settings defined in `config.test.js` will override identical settings in `config.js`. This is by design for test environments but can lead to unexpected behavior if not understood. ↓
gotcha The `README` excerpts show `require()` syntax (CommonJS). While `bedrock-test` itself might still support CJS, modern Node.js and Bedrock applications increasingly use ES Modules (`import`/`export`). Mixing CJS `require` with ESM `import` can lead to module resolution issues or unexpected behavior without proper configuration (e.g., `"type": "module"` in `package.json` and correct file extensions). ↓
Install
npm install bedrock-test yarn add bedrock-test pnpm add bedrock-test Imports
- bedrockTest wrong
const bedrockTest = require('bedrock-test');correctimport * as bedrockTest from 'bedrock-test'; - bedrock.events wrong
const bedrock = require('bedrock'); bedrock.events.on('bedrock.test.configure', configureTest);correctimport * as bedrock from '@bedrock/core'; bedrock.events.on('bedrock.test.configure', configureTest); - config.mocha.tests wrong
config.mocha.tests.push(path.join(__dirname, 'mocha'));correct// In test.config.js import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); config.mocha.tests.push(path.join(__dirname, 'mocha'));
Quickstart
import path from 'path';
import { fileURLToPath } from 'url';
import * as bedrock from '@bedrock/core';
import chai from 'chai';
import { describe, it, before, after } from 'mocha';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const expect = chai.expect;
// Minimal Bedrock setup (typically done in a main test.js file)
bedrock.events.on('bedrock.test.configure', configureTest);
bedrock.events.on('bedrock.test.run', () => console.log('Tests starting...'));
bedrock.start().catch(err => {
console.error('Bedrock failed to start:', err);
process.exit(1);
});
function configureTest(config) {
// Load module-specific test configuration
config.mocha = config.mocha || {};
config.mocha.tests = config.mocha.tests || [];
// Example: push a directory containing Mocha test files
config.mocha.tests.push(path.join(__dirname, 'mocha'));
// Example: configuration override (gotcha #1)
config.someFeature = { enabled: false };
config.test = { someFeature: { enabled: true } }; // This will override config.someFeature
console.log('Bedrock test configuration applied.');
}
// Example mock data (mock.data.js)
const mockData = {
user: { id: 'user123', name: 'Test User' },
product: { id: 'prod456', name: 'Test Product' }
};
// Example Mocha test file (e.g., test/mocha/00-user-api.js)
describe('User API', () => {
let db = [];
before(async () => {
// Simulate loading mock data into a 'database'
db.push(mockData.user);
console.log('Setup: User added to mock DB.');
});
after(() => {
// Clean up between tests or after all tests
db = [];
console.log('Cleanup: Mock DB cleared.');
});
it('should retrieve the test user', () => {
const user = db.find(item => item.id === 'user123');
expect(user).to.exist;
expect(user.name).to.equal('Test User');
console.log('Test: User retrieved successfully.');
});
it('should not find a non-existent user', () => {
const user = db.find(item => item.id === 'nonexistent');
expect(user).to.not.exist;
console.log('Test: Non-existent user not found (as expected).');
});
});