Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Генерация полных Python pytest тестов для REST API эндпоинтов с валидацией схемы. Использовать при создании тестов для новых эндпоинтов, добавлении покрытия для CRUD операций или валидации соответствия API с OpenAPI схемами.
.claude/skills/microck-api-test-generator/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 41% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 95% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 80% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 86% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 115% | 0% |
Generate comprehensive Python pytest tests for MikoPBX REST API endpoints with full parameter coverage, schema validation, and edge case testing.
Analyzes DataStructure.php files and generates complete pytest test suites including:
Use this skill when you need to:
When the user requests test generation:
/pbxcore/api/v3/extensions)bash find /Users/nb/PhpstormProjects/mikopbx/Core/src/PBXCoreREST/Lib -name "DataStructure.php" | grep -i "{resource}"
Extract from DataStructure.php:
Use the complete template from test-template.py
{ResourceName} placeholderspythontests/api/ ├── test_{resource}_api.py # Main test file └── conftest.py # Shared fixtures
Each test file should have these test classes:
pythonclass TestCreate{ResourceName}: """Test POST endpoint for creating resources""" - test_create_with_valid_data() - test_create_missing_required_field() - test_create_with_invalid_type() class TestGet{ResourceName}: """Test GET endpoint for retrieving resources""" - test_get_all() - test_get_by_id() - test_get_nonexistent() class TestUpdate{ResourceName}: """Test PUT/PATCH endpoints for updating resources""" - test_update_with_valid_data() - test_patch_partial_update() class TestDelete{ResourceName}: """Test DELETE endpoint for removing resources""" - test_delete_existing() - test_delete_nonexistent() class TestSchemaValidation{ResourceName}: """Test response schema validation""" - test_response_matches_openapi_schema() class TestEdgeCases{ResourceName}: """Test edge cases and boundary conditions""" - test_special_characters_in_fields() - test_empty_string_values() - test_boundary_values()
python@pytest.fixture def auth_token(): """Get authentication token""" response = requests.post( f"{BASE_URL}/pbxcore/api/v3/auth/login", json={"login": "admin", "password": "123456789MikoPBX#1"}, verify=False ) return response.json()["data"]["access_token"] @pytest.fixture def headers(auth_token): """Standard headers with authentication""" return { "Authorization": f"Bearer {auth_token}", "Content-Type": "application/json" }
pythondef test_create_with_valid_data(self, headers): """Test creating a resource with all valid required parameters""" payload = { # Based on DataStructure.php } response = requests.post( f"{BASE_URL}{API_PATH}", json=payload, headers=headers, verify=False ) assert response.status_code == 200, f"Expected 200, got {response.status_code}: {response.text}" data = response.json() assert "data" in data assert "id" in data["data"] # Validate returned values match input for key, value in payload.items(): assert data["data"][key] == value
pythondef test_create_missing_required_field(self, headers): """Test validation when required field is missing""" payload = { # Missing required field } response = requests.post( f"{BASE_URL}{API_PATH}", json=payload, headers=headers, verify=False ) assert response.status_code == 400 assert "messages" in response.json()
pythondef test_special_characters_in_fields(self, headers): """Test handling of special characters""" special_chars = "Test <script>alert('xss')</script> & \"quotes\"" payload = { "string_field": special_chars, } response = requests.post(...) assert response.status_code == 200 assert response.json()["data"]["string_field"] == special_chars
When analyzing DataStructure.php, extract these key elements:
phppublic static function getParameterDefinitions(): array { return [ 'request' => [ 'POST' => [ 'parameter_name' => [ 'type' => 'string', // Extract type 'description' => 'Description', // Extract description 'example' => 'value', // Use for test data 'required' => true, // Required vs optional 'default' => 'default_value', // Default value 'enum' => ['val1', 'val2'], // Valid enum values 'pattern' => '^[a-z]+$', // Regex pattern 'minLength' => 1, // Min length 'maxLength' => 100, // Max length ], ], ], ]; }
example and default valuesAdd to the top of each test file:
python""" Tests for {ResourceName} API endpoint API Endpoint: /pbxcore/api/v3/{resource-path} DataStructure: src/PBXCoreREST/Lib/{ResourceName}/DataStructure.php Test Coverage: - CRUD operations (Create, Read, Update, Delete) - Required vs optional parameters - Data type validations - Enum value validations - Pattern validations (regex) - Boundary conditions (min/max values) - Special characters and edge cases - Schema validation (when SCHEMA_VALIDATION_STRICT=1) Requirements: - pytest - requests - Docker container running with MikoPBX Run tests: pytest tests/api/test_{resource_name}.py -v Run with schema validation: # Ensure SCHEMA_VALIDATION_STRICT=1 is set in container pytest tests/api/test_{resource_name}.py -v """
Always generate:
bash# Run all API tests pytest tests/api/ -v # Run specific endpoint tests pytest tests/api/test_extensions_api.py -v # Run specific test class pytest tests/api/test_extensions_api.py::TestCreateExtensions -v # Run specific test pytest tests/api/test_extensions_api.py::TestCreateExtensions::test_create_with_valid_data -v
bash# Enable schema validation in container docker exec mikopbx_container sh -c 'export SCHEMA_VALIDATION_STRICT=1' # Run tests pytest tests/api/test_extensions_api.py -v
bash# Run only CRUD tests pytest tests/api/ -m crud -v # Skip slow tests pytest tests/api/ -m "not slow" -v # Run smoke tests pytest tests/api/ -m smoke -v
/auth/loginverify=False for self-signed certificateshttps://mikopbx-php83.localhost:8445SCHEMA_VALIDATION_STRICT=1 in containerComplete test templates for copy-paste usage:
Test a new endpoint in 5 steps:
{ResourceName} and {resource-path}pytest tests/api/test_{resource}_api.py -vNeed specific patterns?
User: "Generate pytest tests for the Extensions API endpoint"
Your response should:
/src/PBXCoreREST/Lib/Extensions/DataStructure.phptests/api/test_extensions_api.pyIssue: Test fails with "Unauthorized" Solution: Check that auth_token fixture is working and token is valid
Issue: Schema validation tests don't run Solution: Ensure SCHEMA_VALIDATION_STRICT=1 is set in container
Issue: Tests are flaky Solution: Ensure test isolation - each test should create its own resources
Issue: Container not accessible Solution: Check container is running: docker ps | grep mikopbx
Issue: SSL certificate errors Solution: Ensure verify=False is set in requests
bash# Check container is running docker ps | grep mikopbx # Check environment variable docker exec mikopbx_container env | grep SCHEMA_VALIDATION_STRICT # View API logs docker exec mikopbx_container tail -f /storage/usbdisk1/mikopbx/log/php/error.log # Test API manually curl -k https://mikopbx-php83.localhost:8445/pbxcore/api/v3/system/ping
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 26,418 | 4,940 | -81% | 1 | 1 | 0% | 5,795 | 3,414 | -41% | 0 | 0 | — |
case-02 | fail→fail | 26,515 | 27,380 | +3% | 1 | 1 | 0% | 3,524 | 9,371 | +166% | 0 | 0 | — |
case-03 | fail→pass | 28,636 | 24,553 | -14% | 1 | 1 | 0% | 6,230 | 8,796 | +41% | 0 | 0 | — |
case-04 | fail→pass | 12,013 | 7,797 | -35% | 1 | 1 | 0% | 2,408 | 4,706 | +95% | 0 | 0 | — |
case-05 | fail→pass | 14,289 | 8,050 | -44% | 1 | 1 | 0% | 2,596 | 4,684 | +80% | 0 | 0 | — |
case-06 | fail→pass | 13,558 | 6,535 | -52% | 1 | 1 | 0% | 2,286 | 4,262 | +86% | 0 | 0 | — |
case-07 | fail→fail | 11,450 | 13,079 | +14% | 1 | 1 | 0% | 2,055 | 5,967 | +190% | 0 | 0 | — |
case-08 | pass→pass | 14,623 | 10,348 | -29% | 1 | 1 | 0% | 2,913 | 5,175 | +78% | 0 | 0 | — |
case-09 | fail→pass | 13,149 | 11,228 | -15% | 1 | 1 | 0% | 2,486 | 5,338 | +115% | 0 | 0 | — |
case-10 | fail→fail | 15,613 | 13,537 | -13% | 1 | 1 | 0% | 2,958 | 5,761 | +95% | 0 | 0 | — |
case-11 | fail→fail | 14,720 | 14,194 | -4% | 1 | 1 | 0% | 2,784 | 5,931 | +113% | 0 | 0 | — |
case-12 | fail→fail | 20,423 | 12,699 | -38% | 1 | 1 | 0% | 3,669 | 6,079 | +66% | 0 | 0 | — |
case-13 | fail→pass | 13,342 | 1,984 | -85% | 1 | 1 | 0% | 2,308 | 3,440 | +49% | 0 | 0 | — |
case-14 | fail→pass | 9,736 | 3,596 | -63% | 1 | 1 | 0% | 1,598 | 3,744 | +134% | 0 | 0 | — |
case-15 | fail→pass | 7,993 | 3,640 | -54% | 1 | 1 | 0% | 1,390 | 3,778 | +172% | 0 | 0 | — |
case-16 | fail→pass | 11,378 | 2,043 | -82% | 1 | 1 | 0% | 1,954 | 3,437 | +76% | 0 | 0 | — |
case-17 | fail→pass | 10,937 | 3,132 | -71% | 1 | 1 | 0% | 1,733 | 3,624 | +109% | 0 | 0 | — |
case-18 | fail→fail | 8,495 | 3,886 | -54% | 1 | 1 | 0% | 1,582 | 3,854 | +144% | 0 | 0 | — |
case-19 | pass→pass | 16,402 | 15,038 | -8% | 1 | 1 | 0% | 3,387 | 6,552 | +93% | 0 | 0 | — |
case-20 | pass→pass | 15,690 | 7,440 | -53% | 1 | 1 | 0% | 2,796 | 4,548 | +63% | 0 | 0 | — |
case-21 | pass→pass | 22,693 | 26,769 | +18% | 1 | 1 | 0% | 4,813 | 8,989 | +87% | 0 | 0 | — |
case-22 | pass→pass | 19,112 | 18,047 | -6% | 1 | 1 | 0% | 4,134 | 7,375 | +78% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.