Metadata-Version: 2.4
Name: testaxiom
Version: 0.1.1
Summary: AI-Powered Test Design Engine — from requirements to mathematically optimal test cases using ISTQB methodology
Project-URL: Homepage, https://github.com/Yaniv2809/testaxiom
Project-URL: Repository, https://github.com/Yaniv2809/testaxiom
Project-URL: Issues, https://github.com/Yaniv2809/testaxiom/issues
Author-email: Yaniv <yaniv2809@users.noreply.github.com>
License: MIT
License-File: LICENSE
Keywords: ai-testing,boundary-value-analysis,decision-table,equivalence-partitioning,istqb,pairwise-testing,qa,test-case-generation,test-design,testing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.9
Provides-Extra: ai
Requires-Dist: anthropic>=0.30.0; extra == 'ai'
Provides-Extra: all
Requires-Dist: anthropic>=0.30.0; extra == 'all'
Requires-Dist: pytest-cov>=5.0; extra == 'all'
Requires-Dist: pytest>=8.0; extra == 'all'
Requires-Dist: ruff>=0.4.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# TestAxiom

**From requirements to mathematically optimal test cases — with AI intelligence and ISTQB methodology.**

TestAxiom is an AI-Powered Test Design Engine that combines Large Language Model intelligence with deterministic, mathematically-grounded test design techniques.

---

## Why TestAxiom?

Most AI test generators just throw requirements at an LLM and say "generate tests." The result: bloated, unexplainable, untraceable test suites. Mathematical tools like PICT are precise but require manual parameter extraction.

**TestAxiom bridges the gap.** Every test case comes with:
- The **technique** that generated it (EP, BVA, Decision Table, Pairwise, State Transition)
- The **mathematical rationale** explaining WHY this specific value was chosen
- Full **traceability** from requirement → technique → test case

---

## Quick Start

```bash
pip install testaxiom
pip install testaxiom[ai]   # optional: for AI requirement parsing
```

### Python API

```python
from testaxiom import analyze

result = analyze("age", param_type="int", valid_range=(18, 65))
print(result.summary())
```

Output:
```
═══ TestAxiom Analysis: age ═══
Techniques applied: EP, BVA
Test cases generated: 7  (87% reduction from 50 exhaustive)

  [EP]  EP-age-001: input=10   → ✗ invalid
         ↳ Equivalence Partitioning: below valid range (18–65). Any value here behaves identically.
  [EP]  EP-age-002: input=30   → ✓ valid
         ↳ Equivalence Partitioning: representative of valid partition.
  [BVA] BVA-age-001: input=17  → ✗ invalid
         ↳ Boundary Value Analysis: just below minimum (18). Classic off-by-one location.
  ...
```

### CLI

```bash
testaxiom --param age --type int --range 18 65
testaxiom --param age --type int --range 18 65 --bva-mode 3-value --json
```

---

## Show, Don't Tell — Real Use Cases

### 1. Free text → pytest tests in 4 lines

```python
import pytest
from testaxiom.parsers import parse_and_analyze
from testaxiom import exporters

# One sentence of requirements → mathematically grounded test cases
results = parse_and_analyze(
    "User age must be between 18 and 65. "
    "Username must be 3–50 characters."
)

# Inject directly into pytest — no manual work
@pytest.mark.parametrize("input_val, expected", exporters.to_pytest_params(results[0]))
def test_age_validation(input_val, expected, app):
    assert app.validate_age(input_val) == (expected == "valid")
```

### 2. Decision Table: "If cart > $100 and user is VIP, apply 20% discount"

```python
from testaxiom.engines.decision_table import DecisionTableEngine, Condition, Action

engine = DecisionTableEngine()

conditions = [
    Condition("cart_over_100", "Cart total exceeds $100"),
    Condition("user_is_vip",   "User has VIP status"),
]
actions = [Action("apply_20pct_discount")]

def discount_resolver(conds):
    return {"apply_20pct_discount": conds["cart_over_100"] and conds["user_is_vip"]}

rules = engine.generate_full_table(conditions, actions, action_resolver=discount_resolver)
test_cases = engine.generate(conditions, actions, rules=rules)

# → 4 test cases, covering every combination:
# cart=T, vip=T → discount ✓
# cart=T, vip=F → no discount ✗
# cart=F, vip=T → no discount ✗
# cart=F, vip=F → no discount ✗
```

### 3. State Transition: Login flow

```python
from testaxiom.engines.state_transition import (
    State, Transition, InvalidTransition, StateTransitionEngine
)

engine = StateTransitionEngine()

states = [State("logged_out"), State("logged_in"), State("locked")]
transitions = [
    Transition("logged_out", "valid_credentials", "logged_in"),
    Transition("logged_in",  "logout",             "logged_out"),
    Transition("logged_out", "invalid_credentials","locked",    guard="attempts >= 3"),
    Transition("locked",     "admin_unlock",        "logged_out"),
]
invalid = [
    InvalidTransition("locked", "valid_credentials", "Account is locked — must be unlocked first"),
]

test_cases = engine.generate(states, transitions, "logged_out", invalid_transitions=invalid)
# → 4 valid transition tests + 1 negative test, all fully traced
```

### 4. Pairwise: Cross-browser/OS matrix (88% reduction)

```python
from testaxiom.engines.pairwise import PairwiseEngine, Parameter

engine = PairwiseEngine()
params = [
    Parameter("browser", ["Chrome", "Firefox", "Safari", "Edge"]),
    Parameter("os",      ["Windows", "macOS", "Linux"]),
    Parameter("lang",    ["en", "he", "ar", "fr"]),
]

cases = engine.generate(params)
# Exhaustive: 4 × 3 × 4 = 48 combinations
# Pairwise:   ~12 test cases — covers every browser×os, browser×lang, os×lang pair
print(cases[0].rationale)
# → "Pairwise test 1/12: covers unique parameter pairs ... 75% reduction"
```

---

## pytest Integration

TestAxiom output plugs directly into `@pytest.mark.parametrize`:

```python
from testaxiom import analyze, exporters
import pytest

result = analyze("price", param_type="float", valid_range=(0.01, 9999.99))

@pytest.mark.parametrize("price, expected", exporters.to_pytest_params(result))
def test_price_validation(price, expected, pricing_service):
    result = pricing_service.validate(price)
    assert result.status == expected
    # Each test is individually named: BVA-price-001, EP-price-002, ...
```

`to_pytest_params()` returns `pytest.param` objects with auto-generated IDs (`EP-age-001`, `BVA-age-003`, etc.) so failures are immediately traceable to their ISTQB technique.

---

## AI Requirement Parser

### Setup

```bash
pip install testaxiom[ai]
export ANTHROPIC_API_KEY="sk-ant-..."   # or set in your environment
```

### Usage

```python
from testaxiom.parsers import parse_requirements, parse_and_analyze

# Extract parameters from free text
specs = parse_requirements(
    "Cart total must be between $0 and $10,000. "
    "Discount percentage: 0–100, must be divisible by 5. "
    "User tier: bronze, silver, gold, platinum."
)

# Or: parse + run full analysis in one call
results = parse_and_analyze("Age must be 18–65", bva_mode="3-value")
for r in results:
    print(r.summary())
```

### Privacy & Security

- Your requirements text is sent to the **Anthropic API** (Claude) for parsing.
- TestAxiom uses your own `ANTHROPIC_API_KEY` — no data is routed through TestAxiom servers.
- The system prompt is **prompt-cached** (Anthropic's caching feature) to reduce latency and cost on repeated calls — no persistent storage of your data.
- If you're working with sensitive specifications, review [Anthropic's privacy policy](https://www.anthropic.com/legal/privacy) before use. All other TestAxiom engines (EP, BVA, Decision Table, Pairwise, State Transition) are **fully local** and send no data anywhere.

---

## Supported Techniques

| Technique | Description |
|-----------|-------------|
| **Equivalence Partitioning (EP)** | Divides input space into partitions — one test per partition |
| **Boundary Value Analysis (BVA)** | Tests at and around partition boundaries (2-value & 3-value modes) |
| **Decision Table** | Covers all combinations of business rules (2ⁿ rules for n conditions) |
| **State Transition** | Tests valid & invalid transitions in state machines |
| **Pairwise (All-Pairs)** | Minimizes combinatorial test sets — covers all value pairs |
| **AI Requirement Parser** | Extracts `ParameterSpec` from free-text requirements via Claude API |

All techniques are **free and open source** (MIT).

---

## Architecture

```
testaxiom/
├── core.py          # Data models (ParameterSpec, TestCase, AnalysisResult)
├── engines/         # Deterministic technique engines — fully local, no AI
│   ├── equivalence_partitioning.py
│   ├── boundary_value.py
│   ├── decision_table.py
│   ├── pairwise.py
│   └── state_transition.py
├── parsers/         # AI layer — optional, requires anthropic package
│   └── ai_requirement_parser.py   # Claude API + tool_use + prompt caching
├── exporters.py     # JSON, Markdown, CSV, Traceability Matrix, pytest params
└── cli.py           # Command-line interface
```

### Key design principles

- **Traceability first** — every test case includes its technique, partition, and mathematical rationale
- **Deterministic** — no randomness except Pairwise's greedy search (seeded, reproducible)
- **Zero required dependencies** — core engines work with no external packages
- **AI is optional** — `pip install testaxiom[ai]` only if you want NLP parsing

---

## License

MIT

## Author

**Yaniv (Yaniv2809)** — AI-Powered QA Engineer
