Skip to main content
AI/MLjeremylongshore

serpapi-ci-integration

'Set up CI/CD for SerpApi integrations with fixture-based testing.

Stars
2,267
Source
jeremylongshore/claude-code-plugins-plus-skills
Updated
2026-05-31
Slug
jeremylongshore--claude-code-plugins-plus-skills--serpapi-ci-integration
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/jeremylongshore/claude-code-plugins-plus-skills/HEAD/plugins/saas-packs/serpapi-pack/skills/serpapi-ci-integration/SKILL.md -o .claude/skills/serpapi-ci-integration.md

Drops the SKILL.md into .claude/skills/serpapi-ci-integration.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

SerpApi CI Integration

Overview

CI for SerpApi should use fixture-based tests (no API credits consumed) for PRs, with optional live integration tests on main branch only.

Instructions

Step 1: GitHub Actions Workflow

name: SerpApi Tests
on: [push, pull_request]

jobs:
  unit-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pip install serpapi pytest
      - run: pytest tests/ -v  # Uses fixtures, no API key needed

  integration:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    env:
      SERPAPI_API_KEY: ${{ secrets.SERPAPI_API_KEY }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pip install serpapi pytest
      - run: pytest tests/integration/ -v --timeout=30

Step 2: Fixture-Based Unit Tests

# tests/test_search_parser.py
import json, pytest

def load_fixture(name):
    with open(f"tests/fixtures/{name}.json") as f:
        return json.load(f)

def test_parse_organic_results():
    result = load_fixture("google_python_tutorial")
    assert "organic_results" in result
    assert len(result["organic_results"]) > 0
    assert result["organic_results"][0]["title"]

def test_parse_youtube_results():
    result = load_fixture("youtube_react_hooks")
    assert "video_results" in result
    assert result["video_results"][0]["length"]

def test_handle_no_results():
    result = load_fixture("google_no_results")
    assert result.get("organic_results", []) == []

Step 3: Live Integration Test (Controlled)

# tests/integration/test_serpapi_live.py
import serpapi, os, pytest

@pytest.fixture
def client():
    key = os.environ.get("SERPAPI_API_KEY")
    if not key:
        pytest.skip("SERPAPI_API_KEY not set")
    return serpapi.Client(api_key=key)

def test_account_has_credits(client):
    account = client.account()
    assert account["plan_searches_left"] > 0

def test_google_search_returns_results(client):
    result = client.search(engine="google", q="python", num=1)
    assert result["search_metadata"]["status"] == "Success"
    assert len(result["organic_results"]) > 0

Error Handling

CI Issue Cause Solution
Fixture not found Missing test data Record fixtures with record_fixture()
Integration test uses credits Tests on every PR Only run on main branch
Flaky results Search results change Use fixtures for deterministic tests

Resources

Next Steps

For deployment patterns, see serpapi-deploy-integration.