level 06 / nosql-testing
NoSQL Validation
Validate MongoDB, Redis, and other NoSQL databases in automated test suites.
NoSQL Landscape for Testers
| Database | Type | Node driver | Test use |
|---|---|---|---|
| MongoDB | Document | mongodb | Validate document shape, queries |
| Redis | Key-value / cache | ioredis | Verify cache entries, TTL, pub/sub |
| Cassandra | Wide column | cassandra-driver | Validate partition queries |
| DynamoDB | Key-value / document | @aws-sdk/client-dynamodb | Validate items, GSI queries |
MongoDB Validation
// Install: npm install mongodb
import { MongoClient } from 'mongodb';
import { test, expect } from '@playwright/test';
let client: MongoClient;
test.beforeAll(async () => {
client = new MongoClient(process.env.MONGO_URL!);
await client.connect();
});
test.afterAll(async () => client.close());
test('user document has required fields', async ({ page }) => {
await page.goto('/register');
await page.fill('[name=email]', 'mongo@test.com');
await page.fill('[name=password]', 'Pass123!');
await page.click('[type=submit]');
await expect(page.getByText('Welcome')).toBeVisible();
const db = client.db('myapp');
const user = await db.collection('users').findOne({ email: 'mongo@test.com' });
expect(user).not.toBeNull();
expect(user!.email).toBe('mongo@test.com');
expect(user!.createdAt).toBeInstanceOf(Date);
expect(user!.passwordHash).toBeDefined();
expect(user!.password).toBeUndefined(); // raw password must NOT be stored
});
MongoDB Query Operators
// Find users created in last hour
const recent = await db.collection('users').find({
createdAt: { $gte: new Date(Date.now() - 3600000) },
}).toArray();
// Count documents matching condition
const count = await db.collection('orders').countDocuments({
status: { $in: ['pending', 'processing'] },
total: { $gt: 100 },
});
// Assert nested field
const order = await db.collection('orders').findOne({ _id: orderId });
expect(order!.shipping.address.city).toBe('London');
Redis Validation
// Install: npm install ioredis
import Redis from 'ioredis';
import { test, expect } from '@playwright/test';
let redis: Redis;
test.beforeAll(async () => {
redis = new Redis(process.env.REDIS_URL!);
});
test.afterAll(async () => redis.quit());
test('login sets session token in Redis', async ({ page }) => {
await page.goto('/login');
await page.fill('[name=username]', 'admin');
await page.fill('[name=password]', 'admin123');
await page.click('[type=submit]');
const cookies = await page.context().cookies();
const sessionId = cookies.find((c) => c.name === 'session')?.value;
expect(sessionId).toBeDefined();
const sessionData = await redis.get(`session:${sessionId}`);
expect(sessionData).not.toBeNull();
const session = JSON.parse(sessionData!);
expect(session.userId).toBeDefined();
});
test('cache key has reasonable TTL', async () => {
const ttl = await redis.ttl('product:catalog:featured');
expect(ttl).toBeGreaterThan(0); // key exists
expect(ttl).toBeLessThan(3600); // max 1 hour cache
});
Redis Data Structures in Tests
// List (e.g., job queue)
const queueLength = await redis.llen('email:queue');
expect(queueLength).toBeGreaterThan(0);
// Hash (e.g., user session)
const fields = await redis.hgetall(`user:${userId}:profile`);
expect(fields.email).toBeDefined();
// Set (e.g., unique visitors)
const isMember = await redis.sismember('active:users', String(userId));
expect(isMember).toBe(1);
// Sorted set (e.g., leaderboard)
const rank = await redis.zrank('leaderboard', String(userId));
expect(rank).not.toBeNull();
DynamoDB (AWS)
import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb';
const dynamo = new DynamoDBClient({ region: 'us-east-1' });
test('item exists in DynamoDB after creation', async ({ request }) => {
const res = await request.post('/items', { data: { id: 'test-123', name: 'Widget' } });
expect(res.status()).toBe(201);
const { Item } = await dynamo.send(new GetItemCommand({
TableName: process.env.DYNAMO_TABLE!,
Key: { id: { S: 'test-123' } },
}));
expect(Item).toBeDefined();
expect(Item!.name.S).toBe('Widget');
});
NoSQL vs SQL Testing Patterns
| Aspect | SQL | NoSQL |
|---|---|---|
| Schema validation | CHECK constraints, column types | Manual field assertion in test |
| Relationships | Foreign key queries | Embed or look up by ID |
| Cleanup | DELETE WHERE or ROLLBACK | deleteOne, del, remove |
| Partial update check | UPDATE ... SET col=val effect | Compare before/after document |