kempo-testing-framework
v1.4.0
Published
The Kempo Testing Framework is a simple testing framework built on the principle that code intended to be ran in the browser should be tested in the browser, code intended to be ran in Node should be tested in Node, and code intended to be ran in both sho
Readme
Kempo Testing Framework
The Kempo Testing Framework is a simple testing framework built on these principles:
- Test in the right environment: Code should be tested in the environment it is written for. Code intended to be ran in the browser is tested in the browser; code intended to be ran in Node is tested in Node. And code intended to be ran in either should be tested in both.
- No mocks, no shims: Test the real thing, not a simulation.
- Simplicity: No custom syntax to learn. Just JavaScript functions and three helpers:
log,pass, andfail. - Zero learning curve: If you know JavaScript, you know how to write tests.
It can be run from a web GUI or from the command line.
This was originally built to test Kempo, but there is nothing Kempo specific about it, it could be used for any JavaScript project.
Requirements
- Node.js version 14.8.0 or higher is required (for ES modules and top-level await support).
- Modern browsers for running browser tests.
If you are using an older version of Node.js, please upgrade to a supported version to use Kempo Testing Framework.
Setup
Install kempo-testing-framework as a dependency in your project:
npm install kempo-testing-framework --save-devTest Types
Kempo supports two types of tests that can coexist in the same test suite:
Browser Tests
Tests that run directly in the browser environment. Best for:
- DOM manipulation
- Browser APIs
- UI components
- Client-side functionality
Node Tests
Tests that run on the server via API calls. Best for:
- Server-side logic
- File system operations
- Node-specific APIs
- Pure JavaScript functions
Each type of test (browser / node) should have its own test file, but both will run
Test File Naming
Kempo supports three types of test files:
[name].browser-test.js— runs only in the browser[name].node-test.js— runs only in Node[name].test.js— runs in both environments
If your code is intended to run in both Node and the browser, you should write a single test file named [name].test.js., otherwise use the environment specific file names [name].browser-test.js and/or [name]node-test.js.
Test Organization
Kempo automatically discovers tests in the tests directory and supports organizing tests in subdirectories for better project structure. You can organize your tests however makes sense for your project:
tests/
├── components/ # UI component tests
│ ├── button.browser-test.js
│ └── modal.browser-test.js
├── api/ # API-related tests
│ ├── auth.node-test.js
│ └── users.node-test.js
├── integration/ # Integration tests
│ └── workflow.test.js
└── utils/ # Utility function tests
└── helpers.test.jsThe framework will recursively search all subdirectories within tests/ to find test files, so you can nest directories as deeply as needed to match your project structure.
Writing Tests
Lifecycle Callbacks
Test files can export the following optional lifecycle functions:
beforeAll- Runs once before all tests (setup)afterAll- Runs once after all tests (cleanup)beforeEach- Runs before each individual testafterEach- Runs after each individual test
Note: All test functions and lifecycle callbacks can be async functions if you need to await asynchronous operations.
Custom Test Pages for Browser Tests
You can specify a custom HTML page for your browser tests by exporting a page string in your test file. This is useful for testing in a specific static environment or reusing a custom fixture across multiple test files.
- The path should be relative to the test file location.
- If no
pageexport is present, the default test page (test.html) will be used.
Example
Suppose you have the following files in your tests directory:
custom-test-page.htmlcustom-page.browser-test.js
Your test file:
// tests/custom-page.browser-test.js
export const page = './custom-test-page.html';
export default {
'should find custom element in custom page': ({ pass, fail }) => {
const el = document.getElementById('custom-test-element');
if (el && el.textContent === 'Hello from custom page!') {
pass('Custom element found and content matches');
} else {
fail('Custom element not found or content mismatch');
}
}
};Your custom HTML page:
<!-- tests/custom-test-page.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Custom Test Page</title>
</head>
<body>
<div id="custom-test-element">Hello from custom page!</div>
<!-- The test runner will inject scripts here -->
</body>
</html>When you run:
npx kempo-test custom-pageKempo will serve your custom HTML page for this test file and inject the test runner, so your tests run in the context of your custom page.
You can share the same custom page across multiple test files by exporting the appropriate relative path in each file.
Example Test File
[name].test.js, [name].browser-test.js, or [name].node-test.js... they all should look exactly the same.
// Import the thing to test
import yourModule from '../../src/yourModule.js';
/* Export the optional lifecycle callbacks */
export const beforeAll = async (log) => {
log('Setting up Node test environment...');
}
export const beforeEach = async (log) => {
log('Setting up Node test for each test')
}
export const beforeEach = async (log) => {
log('Cleaning up Node test for each test')
}
export const afterAll = async (log) => {
log('Cleaning up Node test environment...');
}
/* Export the Tests */
export default {
'should handle basic functionality': async ({pass, fail, log}) => {
const expected = 'abc123';
const result = yourModule.someFunction();
if (result === expected) {
log('✓ Basic functionality works');
pass('Test passed successfully')
} else {
fail(`Expected ${expected}, got ${result}`);
}
},
'should validate input parameters': async ({pass, fail, log}) => {
try {
yourModule.someFunction(null);
fail('Should have thrown an error for null input');
} catch (error) {
log('✓ Properly validates input');
pass('Input validation test passed');
}
}
};Running Tests
CLI (Command-Line Interface)
Run all tests using npx:
npx kempo-testRun only the browser tests:
npx kempo-test -bRun only the node tests:
npx kempo-test -nGUI (webpage)
Run the GUI interface:
npx kempo-test --guiUsing npm Scripts (Optional)
You can add npm scripts to your package.json for convenience:
{
"scripts": {
"tests": "npx kempo-test",
"tests:gui": "npx kempo-test --gui",
"tests:browser": "npx kempo-test -b",
"tests:node": "npx kempo-test -n"
}
}Then run with:
npm run tests # Run all tests
npm run tests:gui # Start GUI
npm run tests:browser # Run only browser tests
npm run tests:node # Run only node testsImportant: npm scripts with npx don't reliably pass additional arguments. If you need to use flags like --show-browser, --log-level, or filters, use npx kempo-test directly instead of npm scripts.
CLI Flags Reference
When running tests via the CLI, you can use various flags to control test execution and output. These flags only affect CLI execution and are ignored when using the GUI (--gui flag).
Note: For flags that take values, you can use either a space or equals: --log-level verbose or --log-level=verbose. Short flags also support equals for value flags: -l verbose or -l=verbose. Examples below use spaces for clarity.
Environment Flags
-b or --browser
- Runs only browser tests (
.browser-test.jsfiles and.test.jsfiles in browser environment) - Example:
npx kempo-test -b - Example with filter:
npx kempo-test -b auth
-n or --node
- Runs only Node tests (
.node-test.jsfiles and.test.jsfiles in Node environment) - Example:
npx kempo-test -n - Example with filter:
npx kempo-test -n user
Log Level Flag
Set the verbosity of output:
-l or --log-level
- Accepts numeric 0–4 or names:
silent|minimal|normal|verbose|debug(alsos|m|n|v|d) - Examples:
npx kempo-test -l debugnpx kempo-test --log-level 3npx kempo-test -l n
Server Configuration Flags
-p or --port
- Specify the port for the browser test server (default: 3000)
- Port must be between 1 and 65535
- Example:
npx kempo-test -b --port 8080 - Example:
npx kempo-test -p 3001
--show-browser or -w
- Show the browser window during browser tests (default: headless mode)
- Useful for debugging browser tests and seeing what's happening
- Example:
npx kempo-test -b --show-browser - Example:
npx kempo-test -b -w
--delay or -d
- Specify a browser pause delay in milliseconds (applies before and after browser tests when the browser window is shown)
- Example:
npx kempo-test -b --show-browser --delay 2000
--timeout or -t
- Set the timeout for individual tests in milliseconds (default: 30000ms)
- Tests that run longer than this timeout will be terminated and marked as failed
- Minimum value: 1000ms (1 second)
- Example:
npx kempo-test --timeout 60000(60 second timeout) - Example:
npx kempo-test -t 10000(10 second timeout)
Combining Flags
You can combine multiple flags for precise control:
# Run only browser tests with verbose-like output using log level
npx kempo-test -b -l verbose auth
# Run only node tests with minimal output
npx kempo-test -n -l minimal user
# Run all tests silently with a specific filter
npx kempo-test -l silent payment
# Run browser tests with visible browser window, custom port and delay
npx kempo-test -b --show-browser --port 8080 --delay 2000
# Run tests with a custom timeout for slow-running tests
npx kempo-test --timeout 60000
# Run browser tests with custom timeout and visible browser
npx kempo-test -b --show-browser --timeout 10000Running Specific or Filtered Tests
Kempo supports two levels of filtering to help you run only the tests you need:
File-Level Filtering
You can filter which test files to run by providing a partial filename (substring) as an argument. All test files whose names include the substring will be run. This works for both full and partial names, and matches anywhere in the filename (not just the start).
For example, if you have test files named auth.browser-test.js, auth.node-test.js, user-auth.test.js, and payment.test.js:
Run all tests with auth in the name (in both environments):
npx kempo-test authRun only the browser tests with auth in the name:
npx kempo-test -b authRun only the node tests with auth in the name:
npx kempo-test -n authIndividual Test Filtering
You can also filter individual tests within files by providing a second argument. This will find files matching the first filter, then within those files, run only tests whose names (object keys) contain the second filter.
Using the same example files, if your auth.browser-test.js contains tests like:
export default {
'should handle user login validation': async ({pass, fail, log}) => { /* ... */ },
'should handle user logout process': async ({pass, fail, log}) => { /* ... */ },
'should validate password requirements': async ({pass, fail, log}) => { /* ... */ }
};Run only tests containing "login" in files containing "auth":
npx kempo-test auth loginRun only browser tests containing "logout" in files containing "auth":
npx kempo-test -b auth logoutBoth file and test filtering are case-insensitive and use substring matching.
If you do not provide any filters, all test files will be auto-discovered and run.
Help
Get usage instructions and see all available options:
npx kempo-test --help