Skip to content

Testing Guide

Comprehensive testing documentation for the Yappa Knowledge Hub POC.

Overview

The project uses a multi-layered testing approach:

  • Unit Tests: Test individual services and utilities in isolation
  • Integration Tests: Test Slack handlers with mocked dependencies
  • API Tests: Test Symfony REST API endpoints
  • E2E Tests: Test complete workflows across the system

Test Stack

Node.js / Slack Bot

  • Framework: Jest 29.7.0
  • HTTP Mocking: Nock 13.5.0
  • Test Runner: Node with ES modules support

Symfony / Backend

  • Framework: PHPUnit 9.5
  • Test Type: WebTestCase for API testing
  • Database: SQLite in-memory for tests

Directory Structure

tests/
 unit/                    # Unit tests for services
    services/
        knowledge.test.js
        categories.test.js
        urlScraper.test.js
 integration/             # Integration tests for handlers
    handlers/
        events.test.js
        interactions.test.js
        commands.test.js
 api/                     # API endpoint tests
    knowledge.test.js
    categories.test.js
 e2e/                     # End-to-end workflow tests
    workflows.test.js
 fixtures/                # Mock data and test fixtures
     mockData.js

backend/tests/
 bootstrap.php            # PHPUnit bootstrap
 Entity/                  # Entity unit tests
    KnowledgeTest.php
    CategoryTest.php
 Controller/              # API controller tests
     KnowledgeControllerTest.php
     CategoryControllerTest.php

Running Tests

Node.js Tests

Run all tests:

bash
npm test

Run specific test suites:

bash
npm run test:unit          # Unit tests only
npm run test:integration   # Integration tests only
npm run test:api          # API tests only
npm run test:e2e          # E2E tests only

Watch mode for development:

bash
npm run test:watch

Generate coverage report:

bash
npm run test:coverage

Symfony Tests

Run all PHPUnit tests:

bash
cd backend
./vendor/bin/phpunit

Run specific test suites:

bash
./vendor/bin/phpunit tests/Entity
./vendor/bin/phpunit tests/Controller

Run with coverage:

bash
./vendor/bin/phpunit --coverage-html coverage

Test Categories

1. Unit Tests

Test individual services in isolation with mocked dependencies.

Example: Knowledge Service

javascript
describe('Knowledge Service', () => {
  it('should add knowledge with complete data', async () => {
    const mockResponse = { data: mockKnowledge };
    axios.post.mockResolvedValue(mockResponse);

    const result = await knowledgeService.addKnowledge(data, 'U12345');

    expect(axios.post).toHaveBeenCalledWith(
      'http://localhost:8000/api/knowledge',
      expect.objectContaining({ title: 'Test Knowledge' })
    );
  });
});

Coverage:

  • /home/ubuntu/yappa-knowledge-hub/tests/unit/services/knowledge.test.js
  • /home/ubuntu/yappa-knowledge-hub/tests/unit/services/categories.test.js
  • /home/ubuntu/yappa-knowledge-hub/tests/unit/services/urlScraper.test.js

2. Integration Tests

Test Slack handlers with mocked Slack client and service dependencies.

Example: Events Handler

javascript
describe('Events Handler', () => {
  it('should detect and scrape URLs in messages', async () => {
    urlScraperService.scrapeUrlMetadata.mockResolvedValue(mockUrlMetadata);

    await handleMessageEvent({ event, client: mockClient });

    expect(urlScraperService.scrapeUrlMetadata).toHaveBeenCalled();
  });
});

Coverage:

  • /home/ubuntu/yappa-knowledge-hub/tests/integration/handlers/events.test.js
  • /home/ubuntu/yappa-knowledge-hub/tests/integration/handlers/interactions.test.js
  • /home/ubuntu/yappa-knowledge-hub/tests/integration/handlers/commands.test.js

3. API Tests

Test Symfony REST API endpoints with real HTTP requests.

Example: Knowledge API

javascript
describe('Knowledge API Endpoints', () => {
  it('should create new knowledge item', async () => {
    const response = await axios.post(`${API_BASE_URL}/knowledge`, payload);

    expect(response.status).toBe(201);
    expect(response.data.title).toBe('API Test Knowledge');
  });
});

Coverage:

  • /home/ubuntu/yappa-knowledge-hub/tests/api/knowledge.test.js
  • /home/ubuntu/yappa-knowledge-hub/tests/api/categories.test.js

4. E2E Tests

Test complete workflows across the entire system.

Example: Complete Workflow

javascript
describe('Complete Knowledge Management Workflow', () => {
  it('should create category, add knowledge, search, update, and delete', async () => {
    // Create category
    const catResponse = await axios.post(`${API_BASE_URL}/categories`, category);

    // Add knowledge
    const knResponse = await axios.post(`${API_BASE_URL}/knowledge`, knowledge);

    // Search
    const searchResponse = await axios.get(`${API_BASE_URL}/knowledge`, {
      params: { search: 'test' }
    });

    // Cleanup
    await axios.delete(`${API_BASE_URL}/knowledge/${knowledgeId}`);
    await axios.delete(`${API_BASE_URL}/categories/${categoryId}`);
  });
});

Coverage:

  • /home/ubuntu/yappa-knowledge-hub/tests/e2e/workflows.test.js

5. PHPUnit Tests

Test Symfony entities and controllers.

Example: Entity Test

php
class KnowledgeTest extends TestCase
{
    public function testKnowledgeCreation(): void
    {
        $knowledge = new Knowledge();
        $knowledge->setTitle('Test Knowledge');

        $this->assertEquals('Test Knowledge', $knowledge->getTitle());
    }
}

Example: Controller Test

php
class KnowledgeControllerTest extends WebTestCase
{
    public function testCreateKnowledge(): void
    {
        $this->client->request('POST', '/api/knowledge', [], [], [
            'CONTENT_TYPE' => 'application/json',
        ], json_encode(['title' => 'Test']));

        $this->assertResponseStatusCodeSame(201);
    }
}

Coverage:

  • https://github.com/undead2146/KnowledgeHub/blob/main/backend/tests/Entity/KnowledgeTest.php
  • https://github.com/undead2146/KnowledgeHub/blob/main/backend/tests/Entity/CategoryTest.php
  • https://github.com/undead2146/KnowledgeHub/blob/main/backend/tests/Controller/KnowledgeControllerTest.php
  • https://github.com/undead2146/KnowledgeHub/blob/main/backend/tests/Controller/CategoryControllerTest.php

Mock Data

All tests use centralized mock data from /home/ubuntu/yappa-knowledge-hub/tests/fixtures/mockData.js:

javascript
export const mockKnowledge = {
  id: 1,
  title: 'Test Knowledge Item',
  content: 'Test content',
  tags: ['test', 'documentation'],
  category: 'general',
  // ...
};

export const mockCategory = {
  id: 'cat-1',
  name: 'General',
  icon: ':file_folder:',
  // ...
};

Test Configuration

Jest Configuration (package.json)

json
{
  "jest": {
    "testEnvironment": "node",
    "transform": {},
    "extensionsToTreatAsEsm": [".js"],
    "testMatch": ["**/tests/**/*.test.js"],
    "collectCoverageFrom": [
      "src/**/*.js",
      "!src/prototypes/**",
      "!src/app.js"
    ]
  }
}

PHPUnit Configuration (phpunit.xml.dist)

xml
<phpunit bootstrap="tests/bootstrap.php" colors="true">
    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">src</directory>
        </include>
    </coverage>
</phpunit>

Best Practices

1. Test Isolation

  • Each test should be independent
  • Use beforeEach to reset mocks and state
  • Clean up test data in E2E tests

2. Mocking

  • Mock external dependencies (axios, Slack client)
  • Use real implementations for unit under test
  • Keep mocks simple and focused

3. Assertions

  • Test both success and error cases
  • Verify function calls with correct parameters
  • Check response structure and data

4. Coverage Goals

  • Aim for 80%+ code coverage
  • Focus on critical business logic
  • Don't test framework code

5. Test Naming

  • Use descriptive test names
  • Follow pattern: "should [expected behavior] when [condition]"
  • Group related tests with describe blocks

CI/CD Integration

GitHub Actions Example

yaml
name: Tests

on: [push, pull_request]

jobs:
  node-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm install
      - run: npm test
      - run: npm run test:coverage

  php-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
      - run: cd backend && composer install
      - run: cd backend && ./vendor/bin/phpunit

Troubleshooting

Common Issues

Jest ES Module Errors

bash
# Solution: Use NODE_OPTIONS flag
NODE_OPTIONS=--experimental-vm-modules jest

Axios Mock Not Working

javascript
// Ensure mock is imported before the module under test
jest.mock('axios');
import * as service from '../services/knowledge.js';

PHPUnit Database Errors

bash
# Reset test database
cd backend
php bin/console doctrine:database:drop --force --env=test
php bin/console doctrine:database:create --env=test
php bin/console doctrine:migrations:migrate --no-interaction --env=test

API Tests Failing

bash
# Ensure Symfony server is running
cd backend
symfony server:start -d

Writing New Tests

Adding a Unit Test

  1. Create test file in appropriate directory
  2. Import dependencies and mock data
  3. Mock external dependencies
  4. Write test cases with clear descriptions
  5. Run tests to verify

Adding an Integration Test

  1. Create test file in tests/integration/
  2. Mock Slack client and services
  3. Test handler functions with various inputs
  4. Verify correct function calls and responses

Adding an API Test

  1. Create test file in tests/api/
  2. Use axios to make real HTTP requests
  3. Test CRUD operations
  4. Clean up test data

Adding a PHPUnit Test

  1. Create test file in backend/tests/
  2. Extend appropriate base class (TestCase or WebTestCase)
  3. Write test methods with test prefix
  4. Use PHPUnit assertions

Coverage Reports

View coverage reports:

Node.js:

bash
npm run test:coverage
open coverage/index.html

Symfony:

bash
cd backend
./vendor/bin/phpunit --coverage-html coverage
open coverage/index.html

Continuous Testing

For active development, use watch mode:

bash
# Terminal 1: Node.js tests
npm run test:watch

# Terminal 2: Symfony server
cd backend && symfony server:start

# Terminal 3: Run specific tests as needed
npm run test:api

Resources

Summary

This comprehensive test suite provides:

  • 95+ test cases across all layers
  • Unit, integration, API, and E2E coverage
  • Mock data and fixtures for consistency
  • Clear documentation and examples
  • CI/CD ready configuration

Run npm test and cd backend && ./vendor/bin/phpunit to execute the full test suite.