tessl install tessl/npm-mastra@1.0.5Command-line tool for creating, developing, and deploying AI-powered applications with the Mastra framework
Comprehensive testing approaches for Mastra applications.
import { create } from "mastra/dist/commands/create/create";
import { describe, it, beforeEach, afterEach } from "node:test";
import assert from "node:assert";
import { existsSync, rmSync } from "fs";
describe("Mastra Project Creation", () => {
const testProjectName = "test-project";
beforeEach(() => {
// Disable telemetry for tests
process.env.MASTRA_TELEMETRY_DISABLED = "1";
});
afterEach(() => {
// Cleanup created project
if (existsSync(testProjectName)) {
rmSync(testProjectName, { recursive: true, force: true });
}
});
it("should create project with defaults", async () => {
await create({
projectName: testProjectName,
components: ["agents"],
llmProvider: "openai",
addExample: false
});
// Assert project structure
assert.ok(existsSync(`${testProjectName}/package.json`));
assert.ok(existsSync(`${testProjectName}/src/mastra`));
assert.ok(existsSync(`${testProjectName}/src/mastra/agents`));
});
it("should create multiple components", async () => {
await create({
projectName: testProjectName,
components: ["agents", "workflows", "tools"],
llmProvider: "openai",
addExample: true
});
assert.ok(existsSync(`${testProjectName}/src/mastra/agents`));
assert.ok(existsSync(`${testProjectName}/src/mastra/workflows`));
assert.ok(existsSync(`${testProjectName}/src/mastra/tools`));
});
it("should fail if directory exists", async () => {
// Create directory first
await create({
projectName: testProjectName,
components: ["agents"],
llmProvider: "openai"
});
// Try to create again
await assert.rejects(
async () => {
await create({
projectName: testProjectName,
components: ["agents"],
llmProvider: "openai"
});
},
{
message: /already exists/
}
);
});
});import { PosthogAnalytics, setAnalytics, getAnalytics } from "mastra/analytics";
import { describe, it, beforeEach, afterEach } from "node:test";
import assert from "node:assert";
describe("Analytics Module", () => {
let analytics: PosthogAnalytics;
beforeEach(() => {
analytics = new PosthogAnalytics({
version: "1.0.1",
apiKey: "test-key",
host: "https://test.posthog.com"
});
setAnalytics(analytics);
});
afterEach(async () => {
await analytics.shutdown();
});
it("should track events", () => {
// This is fire-and-forget, so just verify it doesn't throw
assert.doesNotThrow(() => {
analytics.trackEvent("test_event", { prop: "value" });
});
});
it("should track commands", () => {
assert.doesNotThrow(() => {
analytics.trackCommand({
command: "test",
args: { flag: true },
status: "success"
});
});
});
it("should get global analytics instance", () => {
const instance = getAnalytics();
assert.ok(instance instanceof PosthogAnalytics);
});
it("should track command execution", async () => {
const result = await analytics.trackCommandExecution({
command: "test",
args: {},
execution: async () => {
return "success";
}
});
assert.strictEqual(result, "success");
});
});#!/bin/bash
# test-cli.sh
set -e
export MASTRA_TELEMETRY_DISABLED=1
TEST_DIR="/tmp/mastra-test-$$"
# Cleanup function
cleanup() {
rm -rf "$TEST_DIR"
}
trap cleanup EXIT
# Test: Create command
echo "Testing mastra create..."
mastra create test-app \
--dir "$TEST_DIR" \
--components agents \
--llm openai \
--no-example
# Verify structure
test -f "$TEST_DIR/package.json" || exit 1
test -d "$TEST_DIR/src/mastra" || exit 1
# Test: Lint command
echo "Testing mastra lint..."
cd "$TEST_DIR"
mastra lint || exit 1
# Test: Build command
echo "Testing mastra build..."
mastra build --debug || exit 1
test -f ".mastra/output/index.js" || exit 1
echo "All tests passed!"# Dockerfile.test
FROM node:22.13.0-alpine
WORKDIR /app
# Install mastra
RUN npm install -g mastra
# Copy test script
COPY test-cli.sh .
RUN chmod +x test-cli.sh
# Run tests
CMD ["./test-cli.sh"]# Run tests in Docker
docker build -f Dockerfile.test -t mastra-test .
docker run --rm mastra-testimport { Agent } from '@mastra/core';
import { describe, it, mock } from "node:test";
import assert from "node:assert";
describe("Agent Testing", () => {
it("should execute agent with mock LLM", async () => {
// Mock LLM response
const mockLLM = {
generate: mock.fn(async (prompt) => {
return "Mock response";
})
};
const agent = new Agent({
name: "test-agent",
llm: mockLLM as any,
description: "Test agent"
});
const result = await agent.run("test input");
assert.ok(mockLLM.generate.mock.calls.length > 0);
assert.strictEqual(result, "Mock response");
});
});Start dev server:
mastra devOpen Studio:
mastra studioTest agents interactively:
import { describe, it, before, after } from "node:test";
import assert from "node:assert";
import { spawn } from "child_process";
import fetch from "node-fetch";
describe("E2E: Mastra Server", () => {
let serverProcess: any;
const PORT = 4111;
before(async () => {
// Start server
serverProcess = spawn("npx", ["mastra", "dev"], {
env: {
...process.env,
PORT: String(PORT),
MASTRA_TELEMETRY_DISABLED: "1"
}
});
// Wait for server to start
await new Promise(resolve => setTimeout(resolve, 5000));
});
after(() => {
// Stop server
serverProcess.kill();
});
it("should respond to health check", async () => {
const response = await fetch(`http://localhost:${PORT}/health`);
assert.strictEqual(response.status, 200);
});
it("should execute agent", async () => {
const response = await fetch(`http://localhost:${PORT}/api/agents/test-agent`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ input: "test" })
});
assert.strictEqual(response.status, 200);
const data = await response.json();
assert.ok(data.output);
});
});import { Scorer } from '@mastra/core';
import { describe, it } from "node:test";
import assert from "node:assert";
describe("Keyword Coverage Scorer", () => {
const scorer = new Scorer({
name: "keyword-coverage",
type: "code",
evaluate: async (input, output, context) => {
const keywords = context.requiredKeywords || [];
const outputLower = output.toLowerCase();
const covered = keywords.filter(k =>
outputLower.includes(k.toLowerCase())
);
const score = keywords.length > 0
? covered.length / keywords.length
: 1;
return {
score,
passed: score >= 0.8,
details: {
total: keywords.length,
covered: covered.length,
missing: keywords.filter(k => !covered.includes(k))
}
};
}
});
it("should score full coverage as 1.0", async () => {
const result = await scorer.evaluate(
"input",
"output contains foo and bar",
{ requiredKeywords: ["foo", "bar"] }
);
assert.strictEqual(result.score, 1.0);
assert.strictEqual(result.passed, true);
});
it("should score partial coverage correctly", async () => {
const result = await scorer.evaluate(
"input",
"output contains foo only",
{ requiredKeywords: ["foo", "bar", "baz"] }
);
assert.strictEqual(result.score, 1/3);
assert.strictEqual(result.passed, false);
assert.strictEqual(result.details.missing.length, 2);
});
});import { describe, it, mock } from "node:test";
import assert from "node:assert";
describe("LLM Scorer", () => {
it("should evaluate with mock LLM", async () => {
const mockLLM = {
generate: mock.fn(async () => {
return JSON.stringify({
score: 0.9,
reasoning: "High quality response"
});
})
};
// Test scorer implementation with mock
const result = await evaluateWithLLM(mockLLM, "input", "output");
assert.ok(result.score >= 0 && result.score <= 1);
assert.ok(result.reasoning);
});
});// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [
{ duration: '30s', target: 20 }, // Ramp up
{ duration: '1m', target: 50 }, // Stay at peak
{ duration: '30s', target: 0 }, // Ramp down
],
};
export default function () {
const payload = JSON.stringify({
input: 'test input'
});
const params = {
headers: {
'Content-Type': 'application/json',
},
};
const res = http.post('http://localhost:4111/api/agents/my-agent', payload, params);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}# Run load test
k6 run load-test.js# Start with heap profiler
node --inspect --heap-prof npx mastra start
# Or use clinic.js
npm install -g clinic
clinic doctor -- npx mastra startname: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '22.13.0'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npx mastra lint
- name: Run unit tests
run: npm test
- name: Build
run: npx mastra build --debug
env:
MASTRA_TELEMETRY_DISABLED: 1
- name: Run E2E tests
run: npm run test:e2e
env:
MASTRA_TELEMETRY_DISABLED: 1# Install
npm install --save-dev nyc
# Run with coverage
nyc npm test
# Generate report
nyc report --reporter=html// package.json
{
"nyc": {
"include": ["src/**/*.ts"],
"exclude": ["**/*.test.ts", "**/*.spec.ts"],
"extension": [".ts"],
"require": ["ts-node/register"],
"reporter": ["text", "html"],
"all": true
}
}# Run tests with inspector
node --inspect-brk node_modules/.bin/mocha test/**/*.test.ts// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Run Tests",
"program": "${workspaceFolder}/node_modules/.bin/mocha",
"args": ["--require", "ts-node/register", "test/**/*.test.ts"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}beforeEach(() => {
process.env.MASTRA_TELEMETRY_DISABLED = "1";
});afterEach(async () => {
// Close connections
await db.close();
// Remove test files
rmSync(testDir, { recursive: true, force: true });
// Shutdown analytics
await analytics?.shutdown();
});// fixtures/sample-data.ts
export const testAgent = {
name: "test-agent",
description: "Test agent for unit tests",
llm: { provider: "openai", model: "gpt-4o" }
};
// In tests
import { testAgent } from "./fixtures/sample-data";import { mock } from "node:test";
const mockFetch = mock.fn(async () => ({
ok: true,
json: async () => ({ result: "success" })
}));
global.fetch = mockFetch as any;it("should handle missing API key", async () => {
delete process.env.OPENAI_API_KEY;
await assert.rejects(
async () => await agent.run("input"),
{ message: /API key not set/ }
);
});# Run tests in watch mode
npm test -- --watch
# Or with nodemon
nodemon --exec "npm test" --watch src --watch test# .husky/pre-commit
#!/bin/sh
npm test || exit 1
mastra lint || exit 1