Free SKILL.md scraped from GitHub. Clone the repo or copy the file directly into your Claude Code skills directory.
npx versuz@latest install open-metadata-openmetadata-skills-tddgit clone https://github.com/open-metadata/OpenMetadata.gitcp OpenMetadata/SKILL.MD ~/.claude/skills/open-metadata-openmetadata-skills-tdd/SKILL.md---
name: tdd
description: Use when implementing new features or fixing bugs to enforce test-driven development. Guides the RED-GREEN-REFACTOR cycle for Java (JUnit), Python (pytest), and TypeScript (Jest/Playwright) in OpenMetadata.
user-invocable: true
argument-hint: "<feature or bug description>"
---
# Test-Driven Development for OpenMetadata
Enforce RED-GREEN-REFACTOR discipline across all three language stacks.
## When to Use
- Implementing any new feature or behavior
- Fixing bugs (write a test that reproduces the bug first)
- Adding new API endpoints, connectors, or UI components
## The Cycle
### 1. RED - Write a Failing Test
Write the **smallest test** that describes the desired behavior. Run it. It **must fail**. If it passes, your test isn't testing the new behavior.
**Java (JUnit 5):**
```bash
# Write test in openmetadata-service/src/test/ or openmetadata-integration-tests/
mvn test -pl openmetadata-service -Dtest=YourTestClass#yourTestMethod
```
**Python (pytest):**
```bash
source env/bin/activate
cd ingestion
# Write test using pytest style — plain assert, no unittest.TestCase
python -m pytest tests/unit/your_test.py::test_your_function -v
```
**TypeScript (Jest):**
```bash
cd openmetadata-ui/src/main/resources/ui
yarn test path/to/YourComponent.test.ts
```
**Rules for RED:**
- Test one behavior per test
- Use descriptive test names that explain what should happen
- Assert on observable outcomes (API responses, database state, rendered output), not internal method calls
- For Python: use `assert x == y`, not `self.assertEqual(x, y)`
### 2. GREEN - Write the Minimum Code to Pass
Write **only** the code needed to make the test pass. No more.
- Don't add error handling for cases you haven't tested
- Don't generalize — hardcode if that's what the test requires
- Don't clean up or refactor yet
**Run the test again. It must pass.**
### 3. REFACTOR - Clean Up While Green
Now improve the code while keeping tests green:
- Remove duplication
- Improve naming
- Extract methods if needed (but don't over-abstract)
- Run the full test suite for the module to check for regressions
```bash
# Java — format then test
mvn spotless:apply
mvn test -pl openmetadata-service
# Python — format, lint, then test
cd ingestion && make py_format && make py_format_check
python -m pytest tests/unit/your_test.py -v
# TypeScript — lint then test
cd openmetadata-ui/src/main/resources/ui
yarn lint:fix
yarn test path/to/YourComponent.test.ts
```
### 4. Repeat
Go back to RED with the next behavior. Each cycle should take minutes, not hours.
## What to Test Where
| Layer | Test Type | Location | Runner |
|-------|-----------|----------|--------|
| Java REST API | Integration | `openmetadata-integration-tests/` | `mvn verify` |
| Java service logic | Unit | `openmetadata-service/src/test/` | `mvn test` |
| Python connectors | Unit | `ingestion/tests/unit/` | `pytest` |
| Python integration | Integration | `ingestion/tests/integration/` | `pytest` |
| React components | Unit | Co-located `.test.ts` files | `yarn test` |
| UI E2E flows | E2E | `playwright/e2e/` | `yarn playwright:run` |
## Anti-Patterns to Avoid
- **Writing code before the test.** If you catch yourself doing this, stop. Write the test first.
- **Mocking everything.** Mock external boundaries (HTTP clients, third-party APIs), not your own classes. If you need 3+ mocks, write an integration test instead.
- **Testing implementation details.** Don't assert on internal method calls with `verify()`. Assert on outcomes.
- **Giant test methods.** Each test should verify one behavior. Split multi-assertion tests into separate test cases.
- **Skipping REFACTOR.** The refactor step is where code quality happens. Don't skip it.
## OpenMetadata-Specific Patterns
**Java integration tests** use `BaseEntityIT` with `TestNamespace` for isolation and `OpenMetadataClient` for API calls. Prefer this over heavily mocked unit tests for API testing.
**Python connector tests** should test real behavior:
```python
# Good: test the actual parsing logic
def test_parse_table_metadata():
raw = {"name": "users", "columns": [...]}
result = parse_table(raw)
assert result.name == "users"
assert len(result.columns) == 3
# Bad: mock everything and verify calls
def test_parse_table_metadata():
mock_client = MagicMock()
mock_client.get.return_value = {...}
# ... 20 lines of mock setup
verify(mock_client.get).called_once() # proves nothing
```
**Frontend tests** should render components and assert on visible output:
```typescript
// Good: test what the user sees
render(<MyComponent data={testData} />);
expect(screen.getByText('Expected Label')).toBeInTheDocument();
// Bad: test implementation details
expect(component.state.internalFlag).toBe(true);
```