CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/api-testing-first-steps

Get test coverage on an Express/Node API fast — the first 5 tests that catch

94

1.26x
Quality

90%

Does it follow best practices?

Impact

100%

1.26x

Average score across 5 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-4/

Add Testing to a Bookmarks API

Problem/Feature Description

A small team has built a REST API for managing bookmarked URLs. The API has been running in production for two months but has zero automated tests. The engineering lead has asked a new developer to bootstrap the test suite before the next feature sprint begins.

The API is a Node/Express application backed by SQLite. There is no vitest configuration, no test scripts in package.json, and no test files. The new developer needs to set up everything from scratch: install the right packages, configure the test runner, make the app importable by tests, and write the first meaningful test cases.

The lead specifically wants the setup to be complete enough that any team member can run npm test, watch for changes during development, and generate a coverage report — all without additional configuration. The goal is a complete, team-ready testing foundation, not just a minimal proof-of-concept.

Output Specification

Produce the following files in your working directory:

  • package.json — updated with testing dependencies and all required scripts
  • vitest.config.ts — vitest configuration
  • src/server.ts — updated app file (must be importable without starting the server)
  • src/db.ts — database module (should support test isolation)
  • __tests__/api.test.ts — the first test file with initial test coverage

Input Files

The following files are provided as inputs. Extract them before beginning.

=============== FILE: src/server.ts =============== import express from 'express'; import db from './db.js';

const app = express(); app.use(express.json());

app.get('/api/bookmarks', (req, res) => { const bookmarks = db.prepare('SELECT * FROM bookmarks').all(); res.json({ data: bookmarks }); });

app.post('/api/bookmarks', (req, res) => { const { url, title } = req.body; if (!url) { return res.status(400).json({ error: { message: 'url is required' } }); } const result = db.prepare('INSERT INTO bookmarks (url, title) VALUES (?, ?)').run(url, title || ''); const bookmark = db.prepare('SELECT * FROM bookmarks WHERE id = ?').get(result.lastInsertRowid); res.status(201).json({ data: bookmark }); });

app.get('/api/bookmarks/:id', (req, res) => { const bookmark = db.prepare('SELECT * FROM bookmarks WHERE id = ?').get(req.params.id); if (!bookmark) { return res.status(404).json({ error: { message: 'Bookmark not found' } }); } res.json({ data: bookmark }); });

const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(Bookmarks API running on port ${PORT}));

export default app;

=============== FILE: src/db.ts =============== import Database from 'better-sqlite3';

const db = new Database('./bookmarks.db');

db.exec( CREATE TABLE IF NOT EXISTS bookmarks ( id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT NOT NULL, title TEXT ));

export default db;

=============== FILE: package.json =============== { "name": "bookmarks-api", "version": "1.0.0", "type": "module", "scripts": { "start": "node src/server.ts" }, "dependencies": { "express": "^4.18.2", "better-sqlite3": "^9.4.3" }, "devDependencies": { "@types/express": "^4.17.21", "@types/better-sqlite3": "^7.6.8", "typescript": "^5.3.3" } }

evals

tile.json