or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application-creation.mdcontext-session-mocking.mdenvironment-configuration.mdhttp-client-mocking.mdhttp-testing-utilities.mdindex.mdlogging-assertions.mdmock-restoration.mdservice-mocking.md
tile.json

logging-assertions.mddocs/

Logging and Assertions

Log collection, monitoring, and assertion utilities for testing log output with pattern matching and multi-logger support.

Capabilities

Log Collection

Start collecting logger messages for testing and verification purposes.

/**
 * Start collecting logger messages for testing
 * @param {string|Logger} [logger] - Logger instance or name (defaults to app.logger)
 */
app.mockLog(logger);

/**
 * Collection logger message in cluster mode
 * @param {string} [logger] - Logger name (defaults to 'logger')
 */
clusterApp.mockLog(logger);

Usage Examples:

// Basic log collection
describe('logging tests', () => {
  let app;
  
  beforeEach(() => {
    app = mm.app();
    return app.ready();
  });

  afterEach(() => app.close());

  it('should collect default logger messages', async () => {
    app.mockLog(); // Start collecting app.logger messages
    
    // Trigger some logging
    await app.httpRequest()
      .get('/api/test')
      .expect(200);
    
    app.expectLog('Request processed successfully');
  });

  // Named logger collection
  it('should collect specific logger messages', async () => {
    app.mockLog('accessLogger'); // Collect specific logger
    
    await app.httpRequest()
      .get('/api/users')
      .expect(200);
    
    app.expectLog('GET /api/users', 'accessLogger');
  });
});

Log Assertions

Assert the presence or absence of specific log messages and patterns.

/**
 * Assert that a string/pattern exists in logs
 * @param {string|RegExp} str - String or pattern to find
 * @param {string|Logger} [logger] - Logger instance or name
 */
app.expectLog(str, logger);

/**
 * Assert that a string/pattern does not exist in logs
 * @param {string|RegExp} str - String or pattern that should not be found
 * @param {string|Logger} [logger] - Logger instance or name
 */
app.notExpectLog(str, logger);

/**
 * Cluster mode log assertions (string-only)
 * @param {string} str - String to find in logs
 * @param {string} [logger] - Logger name
 */
clusterApp.expectLog(str, logger);
clusterApp.notExpectLog(str, logger);

Usage Examples:

// String matching
it('should log user creation', async () => {
  app.mockLog();
  
  await app.httpRequest()
    .post('/api/users')
    .send({ name: 'Alice' })
    .expect(201);
  
  app.expectLog('User created: Alice');
  app.notExpectLog('Error creating user');
});

// RegExp pattern matching
it('should log request timing', async () => {
  app.mockLog();
  
  await app.httpRequest()
    .get('/api/slow-endpoint')
    .expect(200);
  
  app.expectLog(/Request completed in \d+ms/);
  app.notExpectLog(/Error:/);
});

// Multiple logger testing
it('should log to different loggers', async () => {
  app.mockLog('app');
  app.mockLog('access');
  app.mockLog('error');
  
  await app.httpRequest()
    .post('/api/invalid')
    .send({ invalid: 'data' })
    .expect(400);
  
  app.expectLog('Validation failed', 'app');
  app.expectLog('POST /api/invalid 400', 'access');
  app.expectLog('Invalid request data', 'error');
});

Custom Logger Testing

Test custom loggers and logger configurations.

Usage Examples:

// Custom logger instance
it('should use custom logger', async () => {
  const customLogger = app.getLogger('custom');
  app.mockLog(customLogger);
  
  // Code that uses custom logger
  customLogger.info('Custom operation started');
  customLogger.info('Custom operation completed');
  
  app.expectLog('Custom operation started', customLogger);
  app.expectLog('Custom operation completed', customLogger);
});

// Logger with different levels
it('should capture different log levels', async () => {
  app.mockLog();
  
  app.logger.debug('Debug message');
  app.logger.info('Info message');
  app.logger.warn('Warning message');
  app.logger.error('Error message');
  
  app.expectLog('Debug message');
  app.expectLog('Info message');
  app.expectLog('Warning message');
  app.expectLog('Error message');
});

// Conditional logging based on environment
it('should log based on environment', async () => {
  app.mockEnv('development');
  app.mockLog();
  
  // Code that logs differently in development
  if (app.config.env === 'development') {
    app.logger.debug('Development debug info');
  }
  
  app.expectLog('Development debug info');
});

Error Log Testing

Specifically test error logging and exception handling.

Usage Examples:

// Exception logging
it('should log exceptions', async () => {
  app.mockLog();
  app.mockServiceError('user', 'find', new Error('Database connection failed'));
  
  await app.httpRequest()
    .get('/api/users/123')
    .expect(500);
  
  app.expectLog('Database connection failed');
  app.expectLog(/Error in user\.find/);
});

// Custom error logging
it('should log validation errors', async () => {
  app.mockLog();
  
  await app.httpRequest()
    .post('/api/users')
    .send({ email: 'invalid-email' })
    .expect(400);
  
  app.expectLog('Validation error');
  app.expectLog('Invalid email format');
  app.notExpectLog('User created successfully');
});

// Stack trace logging
it('should include stack traces in error logs', async () => {
  app.mockLog();
  
  const error = new Error('Test error');
  app.mockServiceError('test', 'method', error);
  
  try {
    await app.service.test.method();
  } catch (e) {
    // Error should be logged with stack trace
  }
  
  app.expectLog('Test error');
  app.expectLog(/at.*test.*method/); // Stack trace pattern
});

Performance and Timing Logs

Test performance-related logging and request timing.

Usage Examples:

// Request timing logs
it('should log request timing', async () => {
  app.mockLog();
  
  await app.httpRequest()
    .get('/api/data')
    .expect(200);
  
  app.expectLog(/GET \/api\/data.*\d+ms/);
});

// Slow request warnings
it('should warn about slow requests', async () => {
  app.mockLog();
  
  // Mock slow service
  app.mockService('data', 'fetch', async () => {
    await new Promise(resolve => setTimeout(resolve, 1000));
    return { data: 'slow response' };
  });
  
  await app.httpRequest()
    .get('/api/slow')
    .expect(200);
  
  app.expectLog(/Slow request detected.*1\d{3}ms/);
});

// Database query timing
it('should log database query performance', async () => {
  app.mockLog('sqlLogger');
  
  await app.httpRequest()
    .get('/api/users')
    .expect(200);
  
  app.expectLog(/SELECT.*FROM users.*\d+ms/, 'sqlLogger');
});

Structured Log Testing

Test structured logging with JSON objects and metadata.

Usage Examples:

// JSON log entries
it('should log structured data', async () => {
  app.mockLog();
  
  app.logger.info('User action', {
    userId: 123,
    action: 'login',
    ip: '192.168.1.1',
    userAgent: 'test-client'
  });
  
  app.expectLog('User action');
  app.expectLog(/"userId":123/);
  app.expectLog(/"action":"login"/);
});

// Log metadata verification
it('should include request metadata in logs', async () => {
  app.mockLog();
  
  await app.httpRequest()
    .get('/api/users')
    .set('x-request-id', 'req-123')
    .expect(200);
  
  app.expectLog(/"requestId":"req-123"/);
  app.expectLog(/"method":"GET"/);
  app.expectLog(/"url":"\/api\/users"/);
});

Log File Testing

Test logging to files and file-based log assertions.

Usage Examples:

// File-based log testing (when not using mockLog)
it('should write to log file', async () => {
  // Don't call mockLog to test file-based logging
  await app.httpRequest()
    .get('/api/test')
    .expect(200);
  
  // expectLog will read from file when no mockLog was called
  app.expectLog('Request completed');
});

// Multiple log files
it('should write to different log files', async () => {
  await app.httpRequest()
    .post('/api/error-prone')
    .send({ invalid: 'data' })
    .expect(400);
  
  // Check application log
  app.expectLog('Validation failed', 'app');
  
  // Check error log
  app.expectLog('Request failed', 'errorLogger');
});

Cluster Mode Logging

Specific logging tests for cluster applications.

Usage Examples:

// Cluster application logging
describe('Cluster logging', () => {
  let app;
  
  before(function(done) {
    app = mm.cluster({ baseDir: 'test/fixtures/apps/demo' });
    app.ready(done);
  });
  
  after(function() {
    return app.close();
  });

  it('should log in cluster mode', () => {
    app.mockLog(); // Cluster mode
    
    return app.httpRequest()
      .get('/api/cluster-test')
      .expect(200)
      .then(() => {
        app.expectLog('Cluster request processed');
      });
  });

  it('should log worker information', () => {
    app.mockLog();
    
    return app.httpRequest()
      .get('/api/worker-info')
      .expect(200)
      .then(() => {
        app.expectLog(/Worker PID: \d+/);
      });
  });
});