This document provides guidance on testing the Scraper MCP server.
The project includes a comprehensive test suite with 84% code coverage and 45 passing tests.
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run with coverage report
pytest --cov=scraper_mcp --cov-report=html
# Run specific test file
pytest tests/test_utils.py
# Run specific test class
pytest tests/test_providers.py::TestRequestsProvider
# Run specific test
pytest tests/test_server.py::TestScrapeUrlTool::test_scrape_url_successName Stmts Miss Cover
----------------------------------------------------------------------
src/scraper_mcp/__init__.py 1 0 100%
src/scraper_mcp/providers/__init__.py 3 0 100%
src/scraper_mcp/providers/base.py 18 2 89%
src/scraper_mcp/providers/requests_provider.py 26 2 92%
src/scraper_mcp/server.py 51 5 90%
src/scraper_mcp/utils.py 43 0 100%
----------------------------------------------------------------------
TOTAL 159 26 84%
tests/test_utils.py (21 tests)
- HTML to markdown conversion
- HTML to plain text extraction
- Link extraction with URL resolution
- Metadata extraction (title, meta tags, OpenGraph)
tests/test_providers.py (12 tests)
- URL validation and support
- HTTP scraping with metadata
- Custom timeout and headers
- Error handling (HTTP errors, timeouts, connection failures)
- Redirect following
- User agent handling
tests/test_server.py (12 tests)
scrape_urltool functionalityscrape_url_markdownwith tag strippingscrape_url_textwith custom strippingscrape_extract_linkswith URL resolution
To manually test the server with real URLs:
# Using Python directly
python -m scraper_mcp
# Using Docker
docker-compose up -d# Install MCP CLI tools
uv add mcp[cli]
# Run inspector
uv run mcp dev src/scraper_mcp/server.pyThis will open a web interface where you can:
- List available tools
- Call tools with different parameters
- View responses and metadata
- Test error handling
You can use the Python client to test tools programmatically:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def test_scraper():
server_params = StdioServerParameters(
command="python",
args=["-m", "scraper_mcp"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# Test scrape_url
result = await session.call_tool(
"scrape_url",
arguments={"url": "https://example.com"}
)
print(f"Scraped {len(result.content)} characters")
asyncio.run(test_scraper())The test suite is designed to run in CI/CD environments:
# Example GitHub Actions workflow
- name: Install dependencies
run: uv pip install -e ".[dev]"
- name: Run tests
run: pytest --cov=scraper_mcp --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v3Test fixtures are defined in tests/conftest.py:
sample_html: Complex HTML with various elementssimple_html: Minimal HTML for basic testshtml_with_links: HTML with different link typeshtml_with_metadata: HTML with meta tags and OpenGraph data
Make sure you've installed the package in development mode:
uv pip install -e ".[dev]"Ensure pytest-asyncio is installed and configured:
uv pip install pytest-asyncioInstall pytest-cov:
uv pip install pytest-covWhen adding new functionality:
- Add unit tests for individual functions
- Add integration tests for MCP tool functionality
- Update fixtures if new test data is needed
- Run tests to ensure nothing breaks
- Check coverage to ensure new code is tested
Example test structure:
import pytest
from scraper_mcp.utils import new_function
class TestNewFunction:
"""Tests for new_function."""
def test_basic_case(self):
"""Test basic functionality."""
result = new_function("input")
assert result == "expected"
def test_edge_case(self):
"""Test edge cases."""
result = new_function("")
assert result == ""
def test_error_handling(self):
"""Test error handling."""
with pytest.raises(ValueError):
new_function(None)