Skip to content

Latest commit

 

History

History
458 lines (323 loc) · 11.6 KB

File metadata and controls

458 lines (323 loc) · 11.6 KB
description Run pytest for mssql-python driver
name mssql-python-test
agent agent
model Claude Sonnet 4.5 (copilot)

Run Tests Prompt for microsoft/mssql-python

You are a development assistant helping run pytest for the mssql-python driver.

PREREQUISITES

Before running tests, you MUST complete these checks in order:

Step 1: Activate Virtual Environment

First, check if a venv is already active:

echo $VIRTUAL_ENV

If a path is shown: ✅ venv is active, skip to Step 2.

If empty: Look for existing venv directories:

ls -d myvenv venv .venv testenv 2>/dev/null | head -1
  • If found: Activate it:

    source <venv-name>/bin/activate
  • If not found: Ask the developer:

    "No virtual environment found. Would you like me to:

    1. Create a new venv called myvenv
    2. Use a different venv (tell me the path)
    3. You'll activate it yourself"

    To create a new venv:

    python3 -m venv myvenv && source myvenv/bin/activate && pip install -r requirements.txt pytest pytest-cov && pip install -e .

Verify venv is active:

echo $VIRTUAL_ENV
# Expected: /path/to/mssql-python/<venv-name>

Step 2: Verify pytest is Installed

python -c "import pytest; print('✅ pytest ready:', pytest.__version__)"

If this fails:

pip install pytest pytest-cov

Step 3: Verify Database Connection String

if [ -n "$DB_CONNECTION_STRING" ]; then echo "✅ Connection string is set"; else echo "❌ Not set"; fi

If not set: Ask the developer for their connection string:

"I need your database connection string to run tests. Please provide the connection details:

  • Server (e.g., localhost, your-server.database.windows.net)
  • Database name
  • Username
  • Password

Or provide the full connection string if you have one."

Once the developer provides the details, set it:

export DB_CONNECTION_STRING="SERVER=<SERVER>;DATABASE=<DATABASE>;UID=<USERNAME>;PWD=<PASSWORD>;Encrypt=yes;TrustServerCertificate=yes"

⚠️ SECURITY: TrustServerCertificate=yes is for local development only. Never use in production.

💡 Note: Do NOT include Driver= in your connection string. The driver automatically adds the correct ODBC driver.

Step 4: Verify SQL Server is Running

CRITICAL: Before running tests, verify SQL Server is accessible:

python main.py

If this succeeds: You'll see database listings and "Connection closed successfully" → ✅ Ready to run tests!

If this fails with connection errors:

"❌ SQL Server is not accessible. Please complete the environment setup first:"

Run the setup prompt (#setup-dev-env) which includes:

  1. Installing/starting SQL Server
  2. Configuring connection strings
  3. Verifying ODBC drivers

Common issues:

  • SQL Server not running → See setup prompt for how to start it
  • Wrong connection string → Check server address, port, credentials
  • Firewall blocking connection → Ensure port 1433 is accessible
  • ODBC driver missing → Install "ODBC Driver 18 for SQL Server"

TASK

Help the developer run tests to validate their changes. Follow this process based on what they need.


STEP 1: Choose What to Test

Test Categories

Category Description When to Use
All tests Full test suite (excluding stress) Before creating PR
Specific file Single test file Testing one area
Specific test Single test function Debugging a failure
Stress tests Long-running, resource-intensive Performance validation
With coverage Tests + coverage report Checking coverage

Ask the Developer

"What would you like to test?"

  1. All tests - Run full suite (recommended before PR)
  2. Specific tests - Tell me which file(s) or test name(s)
  3. With coverage - Generate coverage report

STEP 2: Run Tests

Option A: Run All Tests (Default - Excludes Stress Tests)

# From repository root
python -m pytest -v

# This automatically applies: -m "not stress" (from pytest.ini)

Option B: Run All Tests Including Stress Tests

python -m pytest -v -m ""

Option C: Run Only Stress Tests

python -m pytest -v -m stress

Option D: Run Specific Test File

# Single file
python -m pytest tests/test_003_connection.py -v

# Multiple files
python -m pytest tests/test_003_connection.py tests/test_004_cursor.py -v

Option E: Run Specific Test Function

# Specific test
python -m pytest tests/test_003_connection.py::test_connection_basic -v

# Pattern matching
python -m pytest -k "connection" -v
python -m pytest -k "connection and not close" -v

Option F: Run with Coverage

# Basic coverage
python -m pytest --cov=mssql_python -v

# Coverage with HTML report
python -m pytest --cov=mssql_python --cov-report=html -v

# Coverage with specific report location
python -m pytest --cov=mssql_python --cov-report=html:coverage_report -v

Option G: Run Failed Tests Only (Re-run)

# Re-run only tests that failed in the last run
python -m pytest --lf -v

# Re-run failed tests first, then the rest
python -m pytest --ff -v

STEP 3: Understanding Test Output

Test Result Indicators

Symbol Meaning Action
. or PASSED Test passed ✅ Good
F or FAILED Test failed ❌ Fix needed
E or ERROR Test error (setup/teardown) ❌ Check fixtures
s or SKIPPED Test skipped ℹ️ Usually OK
x or XFAIL Expected failure ℹ️ Known issue
X or XPASS Unexpected pass ⚠️ Review

Example Output

tests/test_003_connection.py::test_connection_basic PASSED    [ 10%]
tests/test_003_connection.py::test_connection_close PASSED    [ 20%]
tests/test_004_cursor.py::test_cursor_execute FAILED          [ 30%]

====================== FAILURES ======================
________________ test_cursor_execute _________________

    def test_cursor_execute(cursor):
>       cursor.execute("SELECT 1")
E       mssql_python.exceptions.DatabaseError: Connection failed

tests/test_004_cursor.py:25: DatabaseError
======================================================

STEP 4: Test File Reference

Test Files and What They Cover

File Purpose Requires DB? Requires mssql_py_core?
test_000_dependencies.py Dependency checks No No
test_001_globals.py Global state No No
test_002_types.py Type conversions No No
test_003_connection.py Connection lifecycle Yes No
test_004_cursor.py Cursor operations Yes No
test_005_connection_cursor_lifecycle.py Lifecycle management Yes No
test_006_exceptions.py Error handling Mixed No
test_007_logging.py Logging functionality No No
test_008_auth.py Authentication Yes No
test_019_bulkcopy.py Bulk copy operations Yes Yes

⚠️ Bulkcopy tests require mssql_py_core to be installed. If not installed, the module is automatically skipped. To install it:

bash eng/scripts/install-mssql-py-core.sh

Troubleshooting

❌ "ModuleNotFoundError: No module named 'mssql_python'"

Cause: Package not installed in development mode

Fix:

pip install -e .

❌ "ModuleNotFoundError: No module named 'pytest'"

Cause: pytest not installed or venv not active

Fix:

# Check venv is active
echo $VIRTUAL_ENV

# If empty, activate it (run `#setup-dev-env`)
# If active, install pytest
pip install pytest pytest-cov

❌ "Connection failed" or "Login failed"

Cause: Invalid or missing DB_CONNECTION_STRING

Fix:

# Check the environment variable is set
echo $DB_CONNECTION_STRING

# Set it with correct values (LOCAL DEVELOPMENT ONLY)
# WARNING: Never commit real credentials. TrustServerCertificate=yes is for local dev only.
# Note: Do NOT include Driver= - the driver automatically adds the correct ODBC driver.
export DB_CONNECTION_STRING="SERVER=localhost;DATABASE=testdb;UID=sa;PWD=YourPassword;Encrypt=yes;TrustServerCertificate=yes"

❌ "Timeout error"

Cause: Database server not reachable

Fix:

  • Check server is running
  • Verify network connectivity
  • Check firewall rules
  • Increase timeout: add Connection Timeout=60 to connection string

❌ Tests hang indefinitely

Cause: Connection pool issues, deadlocks, or waiting for unavailable DB

Fix:

# Run with timeout
pip install pytest-timeout
python -m pytest --timeout=60 -v

# Run single test in isolation
python -m pytest tests/test_specific.py::test_name -v -s

# Skip integration tests if no DB available
python -m pytest tests/test_000_dependencies.py tests/test_001_globals.py tests/test_002_types.py tests/test_007_logging.py -v

❌ "ddbc_bindings" import error

Cause: C++ extension not built or Python version mismatch

Fix: Use #build-ddbc to rebuild the extension:

cd mssql_python/pybind && ./build.sh && cd ../..
python -c "from mssql_python import connect; print('OK')"

❌ Bulkcopy tests are skipped ("module not available")

Cause: mssql_py_core is not installed — the bulkcopy tests skip automatically when it can't be imported.

Fix:

# macOS/Linux - from repository root
bash eng/scripts/install-mssql-py-core.sh

# Windows (PowerShell) - from repository root
.\eng\scripts\install-mssql-py-core.ps1

# Verify
python -c "import mssql_py_core; print('✅ mssql_py_core loaded')"

❌ Tests pass locally but fail in CI

Cause: Environment differences (connection string, Python version, OS)

Fix:

  • Check CI logs for specific error
  • Ensure DB_CONNECTION_STRING is set in CI secrets
  • Verify Python version matches CI

❌ Coverage report shows 0%

Cause: Package not installed or wrong source path

Fix:

# Reinstall in dev mode
pip install -e .

# Run with correct package path
python -m pytest --cov=mssql_python --cov-report=term-missing -v

❌ "collected 0 items"

Cause: pytest can't find tests (wrong directory or pattern)

Fix:

# Ensure you're in repository root
pwd  # Should be /path/to/mssql-python

# Check tests directory exists
ls tests/

# Run with explicit path
python -m pytest tests/ -v

Quick Reference

Common Commands

# Run all tests (default, excludes stress)
python -m pytest -v

# Run specific file
python -m pytest tests/test_003_connection.py -v

# Run with keyword filter
python -m pytest -k "connection" -v

# Run with coverage
python -m pytest --cov=mssql_python -v

# Run failed tests only
python -m pytest --lf -v

# Run with output capture disabled (see print statements)
python -m pytest -v -s

# Run with max 3 failures then stop
python -m pytest -v --maxfail=3

# Run with debugging on failure
python -m pytest -v --pdb

pytest.ini Configuration

The project uses these default settings in pytest.ini:

[pytest]
markers =
    stress: marks tests as stress tests (long-running, resource-intensive)

# Default: Skips stress tests
addopts = -m "not stress"

After Running Tests

Based on test results:

  1. All passed → Ready to create/update PR → Use #create-pr
  2. Some failed → Review failures, fix issues, re-run
  3. Coverage decreased → Add tests for new code paths
  4. Need to debug → Use -s flag to see print output, or --pdb to drop into debugger

💡 Tip: If you made C++ changes, ensure you've rebuilt using #build-ddbc first!