Serverless Integration Test with Offline Plugin

Search for a command to run...

No comments yet. Be the first to comment.
Your team has 14 versions of the same code review skill across 5 repos, with no way to sync them. when one improves, the others don't. drop a folder in .claude/skills/ and pray nothing drifts. source

AI agents are unreasonably good at writing SQL. They get specific error messages, fix their own mistakes in one retry, and can introspect query performance with EXPLAIN ANALYZE before you even ask. No

n8n has over 400 integrations. Zapier claims 7,000+. Every single one was hand-built, tested against a moving API, and will eventually break when that API ships a v2. The entire workflow automation in

Part of the "Your Next Startup" series, where I break down startup ideas I think are worth building. Auth0 sold for \(6.5B. Okta is worth \)15B+. CyberArk, Delinea, BeyondTrust, all printing money fro

For as long as software has existed, we've been building two doors into our systems. Door one: the UI, a carefully designed surface where humans point, click, and occasionally rage-quit. Door two: the

The Test we are going to create today will demonstrate adding an integration test (API test) to your serverless project.
The Tech Stack: NodeJS, Jest, Serverless Framework, and the Serverless offline plugin.
The test going to cover the /search route from my devresorces project.
To test a route when you develop a serverless function you usually going to use the offline plugin to run the function locally and test the endpoint.
Let's add Jest to the project this is simple as that:
npm i -D jest
Now let's create the test folder and our first test file inside /tests/search.test.js
//search.test.js
jest.setTimeout(30000); // incease jest timeout to 30s
const rp = require('request-promise'); // http library to create the http call
const { startSlsOffline, stopSlsOffline } = require('./slsUtils');
// utililty to start and stop the serverless offline plugin.
const domain = 'http://localhost:3001'; //make sure to change to the port you are using
beforeAll(async () => {
await startSlsOffline().catch(e => {
console.error(e);
});
});
afterAll(() => {
stopSlsOffline();
});
test('search', async () => {
try {
const res = await rp.get(`${domain}/search?q=jest`);
expect(res).toBeDefined();
const resources = JSON.parse(res);
expect(typeof resources).toBe('object');
expect(resources.length).toBeDefined();
} catch (error) {
throw error;
}
});
Basically what we are doing is running sls offline start before the tests start and in the end we kill the process.
const { spawn } = require('child_process');
let slsOfflineProcess;
const finishLoading = () =>
new Promise((resolve, reject) => {
slsOfflineProcess.stdout.on('data', data => {
if (data.includes('Offline listening on')) {
console.log(data.toString().trim());
console.log(`Serverless: Offline started with PID : ${slsOfflineProcess.pid}`);
resolve('ok');
}
if (data.includes('address already in use')) {
reject(data.toString().trim());
}
});
slsOfflineProcess.stderr.on('data', errData => {
console.log(`Error starting Serverless Offline:\n${errData}`);
reject(errData);
});
});
function startSlsOffline() {
const cmdArr = 'offline start --skipCacheInvalidation --port 3001 --stage dev'.split(' ');
slsOfflineProcess = spawn('sls', cmdArr, { shell: true, cwd: process.cwd() });
return finishLoading();
}
function stopSlsOffline() {
slsOfflineProcess.stdin.write('q\n');
slsOfflineProcess.stdin.pause();
slsOfflineProcess.kill();
console.log('Serverless Offline stopped');
}
module.exports = {
stopSlsOffline,
startSlsOffline
};
If you going to create many test files make sure to move the beforeAll and afterAll to the global config file.
You can also run this test in your CI.
feel free to contact me for more details :)