Claude Marketplaces
SkillsMCP serversMarketplacesDigestTools
Submit

This week in Claude

Every Monday: Claude Code, Agent SDK, MCP, and the Anthropic platform moves worth your time.

Skills by category
Frontend DevelopmentBackend & APIsTesting & QASecurityDevOps & CI/CDGit & Pull RequestsDocumentationCode Review & QualityAI & Agent BuildingSkill Development
MCP servers by category
Sales & MarketingWeb & Browser AutomationDatabasesAI & LLM ToolsCloud & InfrastructureCommunication & MessagingDeveloper ToolsDesign & CreativeDocuments & KnowledgeSearch & Web Crawling
Marketplaces by category
AI Agents & OrchestrationLLM IntegrationDevelopment ToolsFrontend & UIBackend & APIsDatabasesTesting & Code QualityDevOps & CloudSecurity & ComplianceGit & Version Control
Claude Marketplaces

An independent directory of skills, plugins and MCP servers for Claude Code. Not affiliated with Anthropic.

Browse

  • Skills
  • MCP servers
  • Marketplaces
  • Weekly digest
  • Skill index
  • MCP index
  • Marketplace index

Site

  • About
  • Tools
  • Submit
  • Feedback
  • Privacy
  • llms.txt
  • Plugins reference

Maker

  • Snug
  • Agent Caffeine
  • knobs
  • Wax
  • Vectoys
  • mertduzgun.com
Crafted at
Skills/Backend & APIs
https-deeplearning-ai avatar

Generating Cli Tests

https-deeplearning-ai/sc-agent-skills-files

Solid template for writing pytest tests against Typer CLI apps. You get ready-made fixtures for temp storage and sample data, patterns for handling confirmations (the y/n/--force dance), and a breakdown by command type (CRUD operations). The AAA structure examples are clean, and it covers the annoying edge cases like invalid IDs and empty states. Really shines when you're adding test coverage to an existing CLI or want consistent patterns across commands. The CliRunner examples with input strings for confirmations save you from hunting through docs. If you're building task managers, note apps, or any stateful CLI tool, this gets you from zero to decent coverage fast.

GitHub stars
1.3K
last updated
Jun 8, 2026
View on GitHubSave

Install

$ npx -y skills add https-deeplearning-ai/sc-agent-skills-files --skill generating-cli-tests --agent claude-code

Installs into .claude/skills of the current project.

Files

Generating CLI Tests

Patterns for generating tests for Typer CLI commands.

Workflow

  1. Identify command type (Create/Read/Update/Delete/Bulk)
  2. Ensure fixtures exist in conftest.py
  3. Write tests using scenarios below
  4. Run tests to verify

Fixtures (conftest.py)

import json
import pytest
from typer.testing import CliRunner


@pytest.fixture
def runner():
    """CLI test runner."""
    return CliRunner()


@pytest.fixture
def temp_storage(tmp_path, monkeypatch):
    """Empty storage for testing."""
    storage_dir = tmp_path / ".task"
    storage_dir.mkdir()
    storage_file = storage_dir / "tasks.json"
    storage_file.write_text(json.dumps({"version": 1, "tasks": []}))
    monkeypatch.setenv("TASK_STORAGE_PATH", str(storage_file))
    return storage_file


@pytest.fixture
def sample_data(temp_storage):
    """Pre-populated storage."""
    data = {
        "version": 1,
        "tasks": [
            {"title": "First task", "done": False, "priority": "low", "created_at": "2025-01-01T10:00:00", "due_date": None},
            {"title": "Second task", "done": True, "priority": "high", "created_at": "2025-01-01T11:00:00", "due_date": None},
        ]
    }
    temp_storage.write_text(json.dumps(data))
    return data

Test Structure (AAA)

def test_<command>_<scenario>(runner, temp_storage):
    # Arrange - via fixtures

    # Act
    result = runner.invoke(app, ["<command>", "<args>"])

    # Assert
    assert result.exit_code == 0
    assert "<expected>" in result.output

CliRunner Usage

from typer.testing import CliRunner
from task.main import app

runner = CliRunner()

# Basic
result = runner.invoke(app, ["add", "New task"])

# With options
result = runner.invoke(app, ["add", "Task", "--priority", "high"])

# With confirmation
result = runner.invoke(app, ["clear", "1"], input="y\n")  # Accept
result = runner.invoke(app, ["clear", "1"], input="n\n")  # Decline

# Skip confirmation
result = runner.invoke(app, ["clear", "1", "--force"])

Test Scenarios by Command Type

Create/Add

class TestAdd:
    def test_adds_task(self, runner, temp_storage):
        result = runner.invoke(app, ["add", "New task"])
        assert result.exit_code == 0
        assert "Added" in result.output

    def test_with_priority(self, runner, temp_storage):
        result = runner.invoke(app, ["add", "Task", "--priority", "high"])
        assert result.exit_code == 0

    def test_empty_title_shows_error(self, runner, temp_storage):
        result = runner.invoke(app, ["add", ""])
        assert result.exit_code == 2

Read/List

class TestList:
    def test_shows_tasks(self, runner, sample_data):
        result = runner.invoke(app, ["list"])
        assert result.exit_code == 0
        assert "First task" in result.output

    def test_empty_state(self, runner, temp_storage):
        result = runner.invoke(app, ["list"])
        assert "No tasks" in result.output or "empty" in result.output.lower()

    def test_with_filter(self, runner, sample_data):
        result = runner.invoke(app, ["list", "--done"])
        assert result.exit_code == 0

Update/Done

class TestDone:
    def test_marks_done(self, runner, sample_data):
        result = runner.invoke(app, ["done", "1"])
        assert result.exit_code == 0

    def test_not_found(self, runner, temp_storage):
        result = runner.invoke(app, ["done", "999"])
        assert result.exit_code == 1
        assert "not found" in result.output.lower()

Delete/Clear

class TestClear:
    def test_confirmed(self, runner, sample_data):
        result = runner.invoke(app, ["clear", "1"], input="y\n")
        assert result.exit_code == 0
        assert "Deleted" in result.output

    def test_declined(self, runner, sample_data):
        result = runner.invoke(app, ["clear", "1"], input="n\n")
        assert "Cancelled" in result.output

    def test_force(self, runner, sample_data):
        result = runner.invoke(app, ["clear", "1", "--force"])
        assert result.exit_code == 0

    def test_not_found(self, runner, temp_storage):
        result = runner.invoke(app, ["clear", "999", "--force"])
        assert result.exit_code == 1

Edge Cases to Cover

CategoryTest Cases
Invalid InputEmpty string, wrong type, out of range
Not FoundID doesn't exist
BoundaryZero, negative, first/last item
StateAlready done, empty storage
ConfirmationAccept (y), decline (n), force flag

Checklist

  • Test file: tests/test_<command>.py
  • Fixtures in conftest.py
  • Uses CliRunner from typer.testing
  • AAA structure (Arrange, Act, Assert)
  • Tests exit codes: 0, 1, 2
  • Destructive commands: tests y/n and --force
  • Output assertions check expected messages

Running Tests

uv run pytest                       # All tests
uv run pytest -v                    # Verbose
uv run pytest tests/test_add.py    # Specific file

Sponsors

SnugThe clipboard manager you and your agent can use, safelyAgent CaffeineClose your lid, come back to finished workWaxBlock anything with supervision, without erasing your iPhoneOpen StepsSponsoredFree and open-source skills that make AI coding agents easier to understand, verify, and control.

Details

Repository
github.com/https-deeplearning-ai/sc-agent-skills-files
Categories
Backend & APIs, Testing & QA, AI & Agent Building, Python, CLI & Terminal
First seen
Jun 11, 2026

More from https-deeplearning-ai/sc-agent-skills-files

All 4
  • Learning A Tool
  • Reviewing Cli Command
  • Adding Cli Command

Recommended

More Backend & APIs
1huangjia2019 avatardoc-writinghuangjia2019/claude-code-engineeringGenerate API documentation from a route manifest. Use when you have a list of discovered routes and need to produce markdown documentation.0installs
2huangjia2019 avatarquality-checkinghuangjia2019/claude-code-engineeringValidate API documentation against quality standards. Use when you need to verify generated docs are complete and correct.0installs
3huangjia2019 avatarroute-scanninghuangjia2019/claude-code-engineeringScan Express.js source files to discover all API route definitions.0installs
4hypnguyen1209 avatarexploit-developmenthypnguyen1209/offensive-claudePoC development, payload crafting, shellcode generation, ROP chains, heap exploitation, bypass techniques for modern mitigations (ASLR, DEP, CFI, stack canaries0installs
5hypnguyen1209 avatarinitial-accesshypnguyen1209/offensive-claudeModern initial access techniques — phishing, payload delivery, HTML smuggling, ISO/IMG bypass, supply chain attacks, credential stuffing, exposed service exploi0installs
6hypnguyen1209 avatarshellcode-devhypnguyen1209/offensive-claudeShellcode development — PIC techniques, PEB walking, API hashing, null-byte avoidance, encoders, loaders, PE-to-shellcode conversion, cross-platform shellcode0installs