add smoke tests + rationale README #2

Merged
sdk-lead merged 1 commits from plugin/add-smoke-tests into main 2026-05-10 15:05:46 +00:00
2 changed files with 146 additions and 0 deletions

28
tests/README.md Normal file
View File

@ -0,0 +1,28 @@
# Test Rationale — molecule-skill-update-docs
## What this plugin does
`molecule-skill-update-docs` is a prose-only skill: its logic lives entirely in
`skills/update-docs/SKILL.md` (12-step documentation update workflow). The adapter
(`adapters/claude_code.py`) is a thin re-export of `AgentskillsAdaptor` from
`plugins_registry.builtins` — no business logic, no network calls, no side effects.
## What is tested
- `plugin.yaml` is valid YAML with required fields (name, version, runtimes, skills)
- `skills/update-docs/SKILL.md` has valid YAML frontmatter and a body with
a Steps section documenting the update workflow
- `adapters/claude_code.py` exists and re-exports `AgentskillsAdaptor`
- `validate-plugin.py` (`.molecule-ci/scripts/`) exits zero
## What is NOT unit-tested (and why)
The documentation update workflow is prose guidance inside SKILL.md — no Python
function to unit test. Smoke tests cover the artifact structure; full evaluation
requires integration tests against a real workspace with filesystem access.
## Running tests
```bash
python -m pytest tests/ -v
```

118
tests/test_smoke.py Normal file
View File

@ -0,0 +1,118 @@
#!/usr/bin/env python3
"""
Smoke tests for molecule-skill-update-docs.
See tests/README.md for rationale on limited test coverage.
Run: python -m pytest tests/ -v
"""
import os
import sys
import unittest
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
class TestPluginManifest(unittest.TestCase):
"""Verify plugin.yaml is well-formed."""
@classmethod
def setUpClass(cls):
import yaml
manifest_path = os.path.join(REPO_ROOT, 'plugin.yaml')
with open(manifest_path) as f:
cls.manifest = yaml.safe_load(f)
def test_plugin_yaml_loads(self):
self.assertIsInstance(self.manifest, dict)
def test_name(self):
self.assertEqual(self.manifest['name'], 'molecule-skill-update-docs')
def test_version_semver(self):
v = self.manifest['version']
self.assertRegex(v, r'^\d+\.\d+\.\d+$')
def test_description_present(self):
self.assertGreater(len(self.manifest.get('description', '')), 20)
def test_runtime_claude_code(self):
self.assertIn('claude_code', self.manifest.get('runtimes', []))
def test_skill_declared(self):
self.assertIn('update-docs', self.manifest.get('skills', []))
class TestUpdateDocsSkill(unittest.TestCase):
"""Verify skills/update-docs/SKILL.md is well-formed."""
SKILL_PATH = os.path.join(REPO_ROOT, 'skills', 'update-docs', 'SKILL.md')
def test_file_exists(self):
self.assertTrue(os.path.isfile(self.SKILL_PATH))
def test_has_frontmatter(self):
import yaml
with open(self.SKILL_PATH) as f:
content = f.read()
self.assertTrue(content.startswith('---'))
parts = content.split('---', 2)
self.assertEqual(len(parts), 3)
_, frontmatter, _ = parts
data = yaml.safe_load(frontmatter)
self.assertIsInstance(data, dict)
def test_frontmatter_name(self):
import yaml
with open(self.SKILL_PATH) as f:
content = f.read()
parts = content.split('---', 2)
_, frontmatter, _ = parts
data = yaml.safe_load(frontmatter)
self.assertEqual(data['name'], 'update-docs')
def test_body_has_steps(self):
with open(self.SKILL_PATH) as f:
content = f.read()
parts = content.split('---', 2)
_, _, body = parts
self.assertIn('Steps', body)
class TestAdapter(unittest.TestCase):
"""Verify Claude Code adapter is a valid re-export of AgentskillsAdaptor."""
ADAPTER_PATH = os.path.join(REPO_ROOT, 'adapters', 'claude_code.py')
def test_file_exists(self):
self.assertTrue(os.path.isfile(self.ADAPTER_PATH))
def test_re_exports_agentskills_adaptor(self):
with open(self.ADAPTER_PATH) as f:
content = f.read()
self.assertIn('AgentskillsAdaptor', content)
class TestValidatePlugin(unittest.TestCase):
"""Smoke-test validate-plugin.py if present."""
def test_validate_plugin_exits_zero(self):
import subprocess
val_path = os.path.join(REPO_ROOT, '.molecule-ci', 'scripts', 'validate-plugin.py')
if not os.path.isfile(val_path):
self.skipTest("validate-plugin.py not found")
result = subprocess.run(
[sys.executable, val_path],
capture_output=True,
text=True,
cwd=REPO_ROOT,
)
self.assertEqual(
result.returncode, 0,
f"validate-plugin.py failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"
)
self.assertIn('molecule-skill-update-docs', result.stdout)
if __name__ == '__main__':
unittest.main(verbosity=2)