test-component

Keboola Component Tester

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "test-component" with this command: npx skills add keboola/ai-kit/keboola-ai-kit-test-component

Keboola Component Tester

You are an expert at writing comprehensive tests for Keboola Python components. Your job is to ensure components are thoroughly tested with datadir tests, unit tests, and integration tests.

Testing Philosophy

Keboola components should be tested at multiple levels:

  • Datadir Tests (Priority 1) - Functional tests using production-like data directory structure

  • Unit Tests (Priority 2) - Testing individual functions and methods in isolation

  • Integration Tests (Priority 3) - Testing API interactions with mocked responses

Testing Approach

  1. Understand Component Behavior

Before writing tests:

  • Read the component code (src/component.py )

  • Understand what it does (extract, transform, write data)

  • Identify critical paths and edge cases

  • Note external dependencies (APIs, databases)

  1. Start with Datadir Tests

Datadir tests are the primary testing method for Keboola components.

Why datadir tests?

  • Mirror production environment exactly

  • Test the complete component workflow

  • Verify input/output handling

  • Validate state management

  • Check manifest generation

Basic structure:

def setUp(self): """Point to test case directory.""" path = os.path.join( os.path.dirname(file), 'data', 'test_full_load' ) os.environ["KBC_DATADIR"] = path

def test_full_load(self): """Test full data extraction.""" comp = Component() comp.run()

# Verify outputs
out_dir = Path(os.environ["KBC_DATADIR"]) / "out" / "tables"
self.assertTrue((out_dir / "output.csv").exists())

3. Add Unit Tests for Complex Logic

Write unit tests for:

  • Data transformation functions

  • Validation logic

  • Configuration parsing

  • Complex business rules

Example:

def test_transform_record(self): """Test record transformation logic.""" result = transform_record({ "id": "123", "name": "Test", "value": "100" })

self.assertEqual(result["id"], "123")
self.assertEqual(result["value"], 100)  # Converted to int

4. Mock External Dependencies

For API clients and external services, use mocking:

from unittest.mock import patch, MagicMock

@patch('component.ApiClient') def test_api_call(self, mock_client): """Test API integration with mocked response.""" mock_client.return_value.get.return_value = { "data": [{"id": 1}, {"id": 2}] }

comp = Component()
result = comp.fetch_data()

self.assertEqual(len(result), 2)

Test Case Requirements

Datadir Test Structure

Each test case directory must contain:

  1. config.json - Component configuration

{ "parameters": { "#api_key": "test-key", "endpoint": "https://api.example.com", "limit": 100 } }

  1. in/tables/ - Input CSV files (if needed)

in/tables/input.csv in/tables/input.csv.manifest

  1. in/state.json - Previous state (for incremental tests)

{ "last_run": "2024-01-01T00:00:00Z", "last_id": 12345 }

  1. Expected outputs - What the component should produce

out/tables/output.csv out/tables/output.csv.manifest out/state.json

Comprehensive Test Coverage

Tests should cover:

Happy Path:

  • Full load scenario

  • Incremental load scenario

  • Empty result set

  • Single record

  • Multiple records

Error Handling:

  • Invalid configuration (missing required params)

  • Authentication failures

  • API rate limiting

  • Network errors

  • Invalid data format

Edge Cases:

  • Special characters in data

  • Very large datasets

  • Null values

  • Empty strings

  • Unicode characters

State Management:

  • Initial run (no state)

  • Subsequent runs (with state)

  • State persistence

  • State updates

Common Testing Patterns

Testing Configuration Validation

def test_missing_api_key(self): """Test that missing API key raises error.""" # Remove API key from config with self.assertRaises(ValueError) as context: comp = Component() comp.run()

self.assertIn("api_key", str(context.exception))

Testing State Management

def test_incremental_load(self): """Test incremental data loading.""" comp = Component() comp.run()

# Check state was updated
state_file = Path(os.environ["KBC_DATADIR"]) / "out" / "state.json"
with open(state_file) as f:
    state = json.load(f)

self.assertIn("last_run", state)
self.assertGreater(state["last_id"], 0)

Testing CSV Output

def test_output_format(self): """Test CSV output has correct format.""" comp = Component() comp.run()

output_file = Path(os.environ["KBC_DATADIR"]) / "out" / "tables" / "output.csv"

with open(output_file, encoding="utf-8") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

    # Verify columns
    self.assertEqual(reader.fieldnames, ["id", "name", "value"])

    # Verify data
    self.assertGreater(len(rows), 0)
    self.assertIn("id", rows[0])

Testing Manifest Generation

def test_manifest_created(self): """Test that output manifest is created.""" comp = Component() comp.run()

manifest = Path(os.environ["KBC_DATADIR"]) / "out" / "tables" / "output.csv.manifest"
self.assertTrue(manifest.exists())

with open(manifest) as f:
    manifest_data = json.load(f)

self.assertIn("incremental", manifest_data)
self.assertIn("primary_key", manifest_data)

Output Format

When writing tests, provide:

Test Suite

Datadir Tests

Test Case 1: Full Load

  • Location: tests/data/test_full_load/
  • Purpose: Verify complete data extraction
  • Assertions:
    • Output file created
    • Correct number of records
    • Proper manifest generation

Test Case 2: Incremental Load

  • Location: tests/data/test_incremental/
  • Purpose: Verify state-based incremental processing
  • Assertions:
    • State file updated
    • Only new records extracted
    • Incremental flag set in manifest

Unit Tests

test_transform_record()

  • Tests data transformation logic
  • Verifies type conversions
  • Checks field mappings

test_validate_config()

  • Tests configuration validation
  • Verifies required fields
  • Checks parameter types

Running Tests

# Run all tests
uv run pytest

# Run specific test file
uv run pytest tests/test_component.py

# Run with coverage
uv run pytest --cov=src

# Run with verbose output
uv run pytest -v

## Best Practices

### DO:

- ✅ Start with datadir tests (most important)
- ✅ Test both happy path and error cases
- ✅ Use descriptive test names
- ✅ Keep test data realistic but minimal
- ✅ Mock external API calls
- ✅ Verify manifests and state files
- ✅ Test incremental loading
- ✅ Check CSV encoding (UTF-8)

### DON'T:

- ❌ Test implementation details
- ❌ Use real API credentials in tests
- ❌ Create tests that depend on external services
- ❌ Write tests without assertions
- ❌ Forget to clean up test outputs
- ❌ Test only the happy path
- ❌ Skip testing error handling

## Related Documentation

For detailed testing patterns and examples:
- [Testing Guide](../references/testing.md) - Complete testing strategies and patterns

For component development:
- [Architecture Guide](../guides/component-builder/architecture.md)
- [Best Practices](../guides/component-builder/best-practices.md)
- [Running and Testing](../guides/component-builder/running-and-testing.md)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

get-started

No summary provided by upstream source.

Repository SourceNeeds Review
General

gh-process-review

No summary provided by upstream source.

Repository SourceNeeds Review
General

tester

No summary provided by upstream source.

Repository SourceNeeds Review
General

component-builder

No summary provided by upstream source.

Repository SourceNeeds Review