Metadata-Version: 2.1
Name: partest
Version: 1.3.3
Summary: Methodology-driven API/UI autotest harness with OpenAPI coverage, security helpers, and partest-gen monorepo scaffold.
Home-page: https://github.com/Dec01/partest
Author: dec01
Author-email: parschin.ewg@yandex.ru
Project-URL: Source, https://github.com/Dec01/partest
Keywords: autotest api ui coverage openapi partest pytest allure playwright
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Framework :: Pytest
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27.2
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: matplotlib>=3.9.2
Requires-Dist: allure-pytest>=2.8.18
Requires-Dist: pytest-asyncio>=0.23.7
Requires-Dist: pytest>=8.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: requests>=2.31.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: Faker>=13.12.0
Provides-Extra: ui
Requires-Dist: playwright>=1.40.0; extra == "ui"
Requires-Dist: Pillow>=10.0.0; extra == "ui"
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.7; extra == "dev"

# partest 1.3.3

Methodology-driven **API + UI autotest harness** for Python, plus **`partest-gen`**
scaffold for aqa-style monorepo suites.

**Start here:** [QUICKSTART.md](QUICKSTART.md) · [MIGRATION.md](MIGRATION.md)  
**Cookbooks:** [REPORTING](REPORTING.md) · [SECURITY](SECURITY.md) · [UI](UI_QUICKSTART.md) · [RECIPES](RECIPES.md) · [ENTERPRISE](ENTERPRISE.md)

## Install

```bash
pip install partest
pip install partest[ui]    # Playwright + Pillow
# development:
pip install -e ".[ui]"
```

## Quick start — write tests

```python
from partest import ApiClient, TypesTestCases, TrackingApiClient, CreatedRegistry
import partest.reporting as ah
from partest.zorro_report import zorro

types = TypesTestCases

await api_client.make_request(
    "GET",
    "/items/{id}",
    add_url1="/1",
    defining_url="/items/{id}",
    expected_status_code=200,
    validate_model=MyValidator,
    type=types.request_default,
)
```

Coverage report:

```python
report = zorro()  # Allure + coverage_report.html
```

### Harness modules

```python
from partest import TrackingApiClient, CreatedRegistry, TokenManager, BaseRequestBody, Config
from partest.security import SecHttp, build_tampered_set
from partest.validation import BaseResponseValidator, ProblemDetailValidation
import partest.reporting as ah
from partest.env import load_project_env, require_env
from partest.data_marker import marked_name
from partest.ui import BasePage, attach_monitor, compare_images  # partest[ui]
```

| Module | Role |
|--------|------|
| TrackingApiClient | POST track + cleanup |
| TokenManager | OIDC multi-role cache |
| SecHttp | raw httpx security transport |
| build_tampered_set | JWT tampering fixtures |
| Config | headers/params builders |
| reporting | `ah.check_*`, instrumented requests |
| ui | BasePage, PageMonitor, visual, capture_baselines (extra) |

**pytest plugin** auto-loads (`partest.pytest_plugin`): Allure titles from docstring.  
Disable dual hooks: `PARTEST_PYTEST_PLUGIN=0`, `pytest_plugin = False` in confpartest,
or `pytest -p no:partest`.

**Raw body:** `content=` + `content_type=` on `ApiClient` for IncorrectBody.  
**Multi-status:** `expected_status_code=(400, 415)`.

**RiskProfile** (consumer keeps entity registry)::

```python
from partest import RiskProfile
RiskProfile("clients", writes=True, fk_traversal=True)  # level=high
```

**UI baselines:**

```bash
python -m partest.ui.capture_baselines --out src/ui/baselines/reference \
  --scenes scenes.json --dry-run
```

### Coverage: matrix vs flat (confpartest)

| Mode | When | Config |
|------|------|--------|
| **Matrix (default)** | methodology subtype × P1 | ignore flat list; `use_matrix=True` |
| **Flat (legacy)** | old projects | `test_types_coverage = [...]` + `use_matrix=False` |

See [MIGRATION.md](MIGRATION.md) § coverage.

### Test types

Canonical: `request_default`, `request_permissions`, `request_new_object`,
`request_incorrect_body`, `request_elements`, `request_not_found`,
`request_not_allowed`, …  

Legacy aliases still work: `default`, `405`, `elem`, …

`type=` is recommended; auto-inference is high-confidence only for 405/404/broken JSON.

## Scaffold — partest-gen

```bash
partest-gen from-openapi ./my-suite --file openapi.yaml --depth p1 --force
partest-gen init-ui ./my-suite --force
partest-gen sync-openapi ./my-suite --depth p1
partest-gen dump-ir openapi.yaml -o .partest/suite_ir.json
```

| `--depth` | Generates |
|-----------|-----------|
| `resources` | paths + collections (G2) |
| `default` | + payloads/validations + Default/405 tests (G3) |
| `p1` | + full P1 matrix stubs + checklist (G4) |

| UI | Command |
|----|---------|
| With new project | `partest-gen init … --with-ui` |
| Add to existing | `partest-gen init-ui ./my-suite` |

UI suite is **isolated**: no OpenAPI/partest coverage session under `src/ui/`.

See [PROJECT_GEN_ROADMAP.md](PROJECT_GEN_ROADMAP.md).

## Configuration

**confpartest.py**

```python
swagger_files = {
    "myservice": ["local", "docs/openapi.yaml"],
}
test_types_coverage = ["request_default", "request_not_allowed"]  # legacy flat mode
test_types_exception = ["health"]
```

**Fixtures:** domain / `api_client` / `reset_storage` — see generated `conftest.py`.

## Maintainers

- Continue development: [DEVELOPMENT.md](DEVELOPMENT.md)  
- Status board: [IMPLEMENTATION_PLAN.md](IMPLEMENTATION_PLAN.md)  
- Agent rules: repo root `AGENTS.md`  
- Skill: `.grok/skills/partest/`  

## Version

**1.3.0** — core + harness 1.1 + security/http/plugin (1.2) + `partest[ui]` (1.3) + generator G1–G5.
