aboutsummaryrefslogtreecommitdiff
path: root/pairwise-tests
diff options
context:
space:
mode:
Diffstat (limited to 'pairwise-tests')
-rw-r--r--pairwise-tests/LICENSE35
-rw-r--r--pairwise-tests/SKILL.md373
-rw-r--r--pairwise-tests/references/examples.md98
-rw-r--r--pairwise-tests/references/pict_syntax.md83
-rw-r--r--pairwise-tests/scripts/README.md77
-rw-r--r--pairwise-tests/scripts/pict_helper.py207
6 files changed, 873 insertions, 0 deletions
diff --git a/pairwise-tests/LICENSE b/pairwise-tests/LICENSE
new file mode 100644
index 0000000..e40dc44
--- /dev/null
+++ b/pairwise-tests/LICENSE
@@ -0,0 +1,35 @@
+MIT License
+
+Copyright (c) 2025 pypict-claude-skill contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+---
+
+This project uses and acknowledges the following tools:
+
+PICT (Pairwise Independent Combinatorial Testing)
+Copyright (c) Microsoft Corporation
+Licensed under the MIT License
+https://github.com/microsoft/pict
+
+pypict - Python binding for PICT
+Copyright (c) Kenichi Maehashi
+Licensed under the MIT License
+https://github.com/kmaehashi/pypict
diff --git a/pairwise-tests/SKILL.md b/pairwise-tests/SKILL.md
new file mode 100644
index 0000000..e7b45a1
--- /dev/null
+++ b/pairwise-tests/SKILL.md
@@ -0,0 +1,373 @@
+---
+name: pairwise-tests
+description: Generate a minimal test matrix covering all pairwise parameter interactions using PICT (Pairwise Independent Combinatorial Testing). Given a function, feature, or configuration space with many input parameters, identifies parameters + value partitions + inter-parameter constraints, builds a PICT model, and produces a small set of test cases (typically 80-99% fewer than exhaustive) that still hits every 2-way combination of parameter values. Empirically catches 60-90% of combinatorial bugs. Use when a function has 3+ parameters with multiple values each and exhaustive testing would explode (feature flag combinations, permission/role matrices, config matrices, multi-field form validation, API parameter spaces). Do NOT use for functions with 1-2 parameters (just write the cases directly), for regulated contexts where provably exhaustive coverage is required (document as an ADR and write all cases), or for testing non-parametric behavior (happy path, single error case, performance regression — use `/add-tests` for those). Output: PICT model, markdown table of generated test cases, expected result per row. See also `/add-tests` for standard test generation and `testing.md` for the Normal/Boundary/Error category discipline.
+---
+
+# Pairwise Tests (PICT)
+
+This skill enables systematic test case design using PICT (Pairwise Independent Combinatorial Testing). Given requirements or code, it analyzes the system to identify test parameters, generates a PICT model with appropriate constraints, executes the model to generate pairwise test cases, and formats the results with expected outputs.
+
+## When to Use This Skill
+
+Use this skill when:
+- Designing test cases for a feature, function, or system with multiple input parameters
+- Creating test suites for configurations with many combinations
+- Needing comprehensive coverage with minimal test cases
+- Analyzing requirements to identify test scenarios
+- Working with code that has multiple conditional paths
+- Building test matrices for API endpoints, web forms, or system configurations
+
+## Workflow
+
+Follow this process for test design:
+
+### 1. Analyze Requirements or Code
+
+From the user's requirements or code, identify:
+- **Parameters**: Input variables, configuration options, environmental factors
+- **Values**: Possible values for each parameter (using equivalence partitioning)
+- **Constraints**: Business rules, technical limitations, dependencies between parameters
+- **Expected Outcomes**: What should happen for different combinations
+
+**Example Analysis:**
+
+For a login function with requirements:
+- Users can login with username/password
+- Supports 2FA (on/off)
+- Remembers login on trusted devices
+- Rate limits after 3 failed attempts
+
+Identified parameters:
+- Credentials: Valid, Invalid
+- TwoFactorAuth: Enabled, Disabled
+- RememberMe: Checked, Unchecked
+- PreviousFailures: 0, 1, 2, 3, 4
+
+### 2. Generate PICT Model
+
+Create a PICT model with:
+- Clear parameter names
+- Well-defined value sets (using equivalence partitioning and boundary values)
+- Constraints for invalid combinations
+- Comments explaining business rules
+
+**Model Structure:**
+```
+# Parameter definitions
+ParameterName: Value1, Value2, Value3
+
+# Constraints (if any)
+IF [Parameter1] = "Value" THEN [Parameter2] <> "OtherValue";
+```
+
+**Refer to references/pict_syntax.md for:**
+- Complete syntax reference
+- Constraint grammar and operators
+- Advanced features (sub-models, aliasing, negative testing)
+- Command-line options
+- Detailed constraint patterns
+
+**Refer to references/examples.md for:**
+- Complete real-world examples by domain
+- Software function testing examples
+- Web application, API, and mobile testing examples
+- Database and configuration testing patterns
+- Common patterns for authentication, resource access, error handling
+
+### 3. Execute PICT Model
+
+Generate the PICT model text and format it for the user. You can use Python code directly to work with the model:
+
+```python
+# Define parameters and constraints
+parameters = {
+ "OS": ["Windows", "Linux", "MacOS"],
+ "Browser": ["Chrome", "Firefox", "Safari"],
+ "Memory": ["4GB", "8GB", "16GB"]
+}
+
+constraints = [
+ 'IF [OS] = "MacOS" THEN [Browser] IN {Safari, Chrome}',
+ 'IF [Memory] = "4GB" THEN [OS] <> "MacOS"'
+]
+
+# Generate model text
+model_lines = []
+for param_name, values in parameters.items():
+ values_str = ", ".join(values)
+ model_lines.append(f"{param_name}: {values_str}")
+
+if constraints:
+ model_lines.append("")
+ for constraint in constraints:
+ if not constraint.endswith(';'):
+ constraint += ';'
+ model_lines.append(constraint)
+
+model_text = "\n".join(model_lines)
+print(model_text)
+```
+
+**Using the helper script (optional):**
+The `scripts/pict_helper.py` script provides utilities for model generation and output formatting:
+
+```bash
+# Generate model from JSON config
+python scripts/pict_helper.py generate config.json
+
+# Format PICT tool output as markdown table
+python scripts/pict_helper.py format output.txt
+
+# Parse PICT output to JSON
+python scripts/pict_helper.py parse output.txt
+```
+
+**To generate actual test cases**, the user can:
+1. Save the PICT model to a file (e.g., `model.txt`)
+2. Use online PICT tools like:
+ - https://pairwise.yuuniworks.com/
+ - https://pairwise.teremokgames.com/
+3. Or install PICT locally (see references/pict_syntax.md)
+
+### 4. Determine Expected Outputs
+
+For each generated test case, determine the expected outcome based on:
+- Business requirements
+- Code logic
+- Valid/invalid combinations
+
+Create a list of expected outputs corresponding to each test case.
+
+### 5. Format Complete Test Suite
+
+Provide the user with:
+1. **PICT Model** - The complete model with parameters and constraints
+2. **Markdown Table** - Test cases in table format with test numbers
+3. **Expected Outputs** - Expected result for each test case
+
+## Output Format
+
+Present results in this structure:
+
+````markdown
+## PICT Model
+
+```
+# Parameters
+Parameter1: Value1, Value2, Value3
+Parameter2: ValueA, ValueB
+
+# Constraints
+IF [Parameter1] = "Value1" THEN [Parameter2] = "ValueA";
+```
+
+## Generated Test Cases
+
+| Test # | Parameter1 | Parameter2 | Expected Output |
+| --- | --- | --- | --- |
+| 1 | Value1 | ValueA | Success |
+| 2 | Value2 | ValueB | Success |
+| 3 | Value1 | ValueB | Error: Invalid combination |
+...
+
+## Test Case Summary
+
+- Total test cases: N
+- Coverage: Pairwise (all 2-way combinations)
+- Constraints applied: N
+````
+
+## Best Practices
+
+### Parameter Identification
+
+**Good:**
+- Use descriptive names: `AuthMethod`, `UserRole`, `PaymentType`
+- Apply equivalence partitioning: `FileSize: Small, Medium, Large` instead of `FileSize: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10`
+- Include boundary values: `Age: 0, 17, 18, 65, 66`
+- Add negative values for error testing: `Amount: ~-1, 0, 100, ~999999`
+
+**Avoid:**
+- Generic names: `Param1`, `Value1`, `V1`
+- Too many values without partitioning
+- Missing edge cases
+
+### Constraint Writing
+
+**Good:**
+- Document rationale: `# Safari only available on MacOS`
+- Start simple, add incrementally
+- Test constraints work as expected
+
+**Avoid:**
+- Over-constraining (eliminates too many valid combinations)
+- Under-constraining (generates invalid test cases)
+- Complex nested logic without clear documentation
+
+### Expected Output Definition
+
+**Be specific:**
+- "Login succeeds, user redirected to dashboard"
+- "HTTP 400: Invalid credentials error"
+- "2FA prompt displayed"
+
+**Not vague:**
+- "Works"
+- "Error"
+- "Success"
+
+### Scalability
+
+For large parameter sets:
+- Use sub-models to group related parameters with different orders
+- Consider separate test suites for unrelated features
+- Start with order 2 (pairwise), increase for critical combinations
+- Typical pairwise testing reduces test cases by 80-90% vs exhaustive
+
+## Common Patterns
+
+### Web Form Testing
+
+```python
+parameters = {
+ "Name": ["Valid", "Empty", "TooLong"],
+ "Email": ["Valid", "Invalid", "Empty"],
+ "Password": ["Strong", "Weak", "Empty"],
+ "Terms": ["Accepted", "NotAccepted"]
+}
+
+constraints = [
+ 'IF [Terms] = "NotAccepted" THEN [Name] = "Valid"', # Test validation even if terms not accepted
+]
+```
+
+### API Endpoint Testing
+
+```python
+parameters = {
+ "HTTPMethod": ["GET", "POST", "PUT", "DELETE"],
+ "Authentication": ["Valid", "Invalid", "Missing"],
+ "ContentType": ["JSON", "XML", "FormData"],
+ "PayloadSize": ["Empty", "Small", "Large"]
+}
+
+constraints = [
+ 'IF [HTTPMethod] = "GET" THEN [PayloadSize] = "Empty"',
+ 'IF [Authentication] = "Missing" THEN [HTTPMethod] IN {GET, POST}'
+]
+```
+
+### Configuration Testing
+
+```python
+parameters = {
+ "Environment": ["Dev", "Staging", "Production"],
+ "CacheEnabled": ["True", "False"],
+ "LogLevel": ["Debug", "Info", "Error"],
+ "Database": ["SQLite", "PostgreSQL", "MySQL"]
+}
+
+constraints = [
+ 'IF [Environment] = "Production" THEN [LogLevel] <> "Debug"',
+ 'IF [Database] = "SQLite" THEN [Environment] = "Dev"'
+]
+```
+
+## Troubleshooting
+
+### No Test Cases Generated
+
+- Check constraints aren't over-restrictive
+- Verify constraint syntax (must end with `;`)
+- Ensure parameter names in constraints match definitions (use `[ParameterName]`)
+
+### Too Many Test Cases
+
+- Verify using order 2 (pairwise) not higher order
+- Consider breaking into sub-models
+- Check if parameters can be separated into independent test suites
+
+### Invalid Combinations in Output
+
+- Add missing constraints
+- Verify constraint logic is correct
+- Check if you need to use `NOT` or `<>` operators
+
+### Script Errors
+
+- Ensure pypict is installed: `pip install pypict --break-system-packages`
+- Check Python version (3.7+)
+- Verify model syntax is valid
+
+## References
+
+- **references/pict_syntax.md** - Complete PICT syntax reference with grammar and operators
+- **references/examples.md** - Comprehensive real-world examples across different domains
+- **scripts/pict_helper.py** - Python utilities for model generation and output formatting
+- [PICT GitHub Repository](https://github.com/microsoft/pict) - Official PICT documentation
+- [pypict Documentation](https://github.com/kmaehashi/pypict) - Python binding documentation
+- [Online PICT Tools](https://pairwise.yuuniworks.com/) - Web-based PICT generator
+
+## Examples
+
+### Example 1: Simple Function Testing
+
+**User Request:** "Design tests for a divide function that takes two numbers and returns the result."
+
+**Analysis:**
+- Parameters: dividend (number), divisor (number)
+- Values: Using equivalence partitioning and boundaries
+ - Numbers: negative, zero, positive, large values
+- Constraints: Division by zero is invalid
+- Expected outputs: Result or error
+
+**PICT Model:**
+```
+Dividend: -10, 0, 10, 1000
+Divisor: ~0, -5, 1, 5, 100
+
+IF [Divisor] = "0" THEN [Dividend] = "10";
+```
+
+**Test Cases:**
+
+| Test # | Dividend | Divisor | Expected Output |
+| --- | --- | --- | --- |
+| 1 | 10 | 0 | Error: Division by zero |
+| 2 | -10 | 1 | -10.0 |
+| 3 | 0 | -5 | 0.0 |
+| 4 | 1000 | 5 | 200.0 |
+| 5 | 10 | 100 | 0.1 |
+
+### Example 2: E-commerce Checkout
+
+**User Request:** "Design tests for checkout flow with payment methods, shipping options, and user types."
+
+**Analysis:**
+- Payment: Credit Card, PayPal, Bank Transfer (limited by user type)
+- Shipping: Standard, Express, Overnight
+- User: Guest, Registered, Premium
+- Constraints: Guests can't use Bank Transfer, Premium users get free Express
+
+**PICT Model:**
+```
+PaymentMethod: CreditCard, PayPal, BankTransfer
+ShippingMethod: Standard, Express, Overnight
+UserType: Guest, Registered, Premium
+
+IF [UserType] = "Guest" THEN [PaymentMethod] <> "BankTransfer";
+IF [UserType] = "Premium" AND [ShippingMethod] = "Express" THEN [PaymentMethod] IN {CreditCard, PayPal};
+```
+
+**Output:** 12-15 test cases covering all valid payment/shipping/user combinations with expected costs and outcomes.
+
+---
+
+## Attribution
+
+Forked from [omkamal/pypict-claude-skill](https://github.com/omkamal/pypict-claude-skill) — MIT licensed. See `LICENSE` in this directory for the original copyright and terms.
+
+**Local changes:**
+- Skill renamed from `pict-test-designer` to `pairwise-tests`. PICT remains the implementation; the user-facing name leads with the technique (pairwise / combinatorial) rather than the tool brand.
+- Description rewritten to lead with the "what" (pairwise coverage, 2-way interaction), include explicit negative triggers (≤2 parameters, regulated contexts requiring exhaustive coverage, non-parametric testing), and cross-reference `/add-tests` and `testing.md`.
+- Omitted from the fork: `examples/` directory (ATM + gearbox worked examples — useful as a walkthrough, not needed at skill-runtime) and repo-level metadata (README, QUICKSTART, CONTRIBUTING, releases/, .claude-plugin/). The skill-runtime files — SKILL.md, LICENSE, `references/pict_syntax.md`, `references/examples.md`, `scripts/pict_helper.py` + `scripts/README.md` — are intact.
diff --git a/pairwise-tests/references/examples.md b/pairwise-tests/references/examples.md
new file mode 100644
index 0000000..258b1ef
--- /dev/null
+++ b/pairwise-tests/references/examples.md
@@ -0,0 +1,98 @@
+# PICT Examples Reference
+
+> **Note**: This is a placeholder file. Comprehensive examples are coming soon!
+>
+> For now, check out the [examples directory](../examples/) for complete real-world examples.
+
+## Available Examples
+
+### Complete Examples
+- **[ATM System Testing](../examples/atm-specification.md)**: Comprehensive banking ATM system with 31 test cases
+
+### Coming Soon
+
+#### Software Testing
+- Function testing with multiple parameters
+- API endpoint testing
+- Database query validation
+- Algorithm testing
+
+#### Web Applications
+- Form validation
+- User authentication
+- E-commerce checkout
+- Shopping cart operations
+
+#### Configuration Testing
+- System configurations
+- Feature flags
+- Environment settings
+- Browser compatibility
+
+#### Mobile Testing
+- Device and OS combinations
+- Screen sizes
+- Network conditions
+- Permissions
+
+## Pattern Library (Coming Soon)
+
+### Common Constraint Patterns
+
+```
+# Dependency constraints
+IF [FeatureA] = "Enabled" THEN [FeatureB] = "Enabled";
+
+# Exclusive options
+IF [PaymentMethod] = "Cash" THEN [InstallmentPlan] = "None";
+
+# Platform limitations
+IF [OS] = "iOS" THEN [Browser] IN {Safari, Chrome};
+
+# Environment restrictions
+IF [Environment] = "Production" THEN [LogLevel] <> "Debug";
+```
+
+### Boundary Value Patterns
+
+```
+# Numeric boundaries
+Age: 0, 17, 18, 64, 65, 100
+
+# Size categories
+FileSize: 0KB, 1KB, 1MB, 100MB, 1GB
+
+# Time periods
+Duration: 0s, 1s, 30s, 60s, 3600s
+```
+
+### Negative Testing Patterns
+
+```
+# Invalid inputs (using ~ prefix in some PICT variants)
+Email: Valid, Invalid, Empty, TooLong
+Password: Strong, Weak, Empty, SpecialChars
+
+# Error conditions
+NetworkStatus: Connected, Slow, Disconnected, Timeout
+```
+
+## Contributing Examples
+
+Have an example to share? We'd love to include it!
+
+1. Create your example following the structure in [examples/README.md](../examples/README.md)
+2. Include:
+ - Original specification
+ - PICT model
+ - Test cases with expected outputs
+ - Learning points
+3. Submit a pull request
+
+See [CONTRIBUTING.md](../CONTRIBUTING.md) for details.
+
+## External Resources
+
+- [Pairwise Testing Tutorial](https://www.pairwisetesting.com/)
+- [NIST Combinatorial Testing Resources](https://csrc.nist.gov/projects/automated-combinatorial-testing-for-software)
+- [Microsoft PICT Examples](https://github.com/microsoft/pict/tree/main/doc)
diff --git a/pairwise-tests/references/pict_syntax.md b/pairwise-tests/references/pict_syntax.md
new file mode 100644
index 0000000..d25fb57
--- /dev/null
+++ b/pairwise-tests/references/pict_syntax.md
@@ -0,0 +1,83 @@
+# PICT Syntax Reference
+
+> **Note**: This is a placeholder file. Complete syntax documentation is coming soon!
+>
+> For now, please refer to the official PICT documentation:
+> - [Microsoft PICT on GitHub](https://github.com/microsoft/pict)
+> - [PICT User Guide](https://github.com/microsoft/pict/blob/main/doc/pict.md)
+
+## Quick Reference
+
+### Basic Model Structure
+
+```
+# Parameters
+ParameterName: Value1, Value2, Value3
+AnotherParameter: ValueA, ValueB, ValueC
+
+# Constraints (optional)
+IF [ParameterName] = "Value1" THEN [AnotherParameter] <> "ValueA";
+```
+
+### Parameter Definition
+
+```
+ParameterName: Value1, Value2, Value3, ...
+```
+
+### Constraint Syntax
+
+```
+IF <condition> THEN <condition>;
+```
+
+### Operators
+
+- `=` - Equal to
+- `<>` - Not equal to
+- `>` - Greater than
+- `<` - Less than
+- `>=` - Greater than or equal to
+- `<=` - Less than or equal to
+- `IN` - Member of set
+- `AND` - Logical AND
+- `OR` - Logical OR
+- `NOT` - Logical NOT
+
+### Example Constraints
+
+```
+# Simple constraint
+IF [OS] = "MacOS" THEN [Browser] <> "IE";
+
+# Multiple conditions
+IF [Environment] = "Production" AND [LogLevel] = "Debug" THEN [Approved] = "False";
+
+# Set membership
+IF [UserRole] = "Guest" THEN [Permission] IN {Read, None};
+```
+
+## Coming Soon
+
+Detailed documentation will include:
+- Complete grammar specification
+- Advanced features (sub-models, aliasing, seeding)
+- Negative testing patterns
+- Weight specifications
+- Order specifications
+- Examples for each feature
+
+## Contributing
+
+If you'd like to help complete this documentation:
+1. Fork the repository
+2. Add content to this file
+3. Submit a pull request
+
+See [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.
+
+## External Resources
+
+- [Official PICT Documentation](https://github.com/microsoft/pict/blob/main/doc/pict.md)
+- [pypict Documentation](https://github.com/kmaehashi/pypict)
+- [Pairwise Testing Explained](https://www.pairwisetesting.com/)
diff --git a/pairwise-tests/scripts/README.md b/pairwise-tests/scripts/README.md
new file mode 100644
index 0000000..87ea259
--- /dev/null
+++ b/pairwise-tests/scripts/README.md
@@ -0,0 +1,77 @@
+# Scripts
+
+This directory contains helper scripts for working with PICT models and test cases.
+
+## Available Scripts
+
+### pict_helper.py
+
+A Python utility for:
+- Generating PICT models from JSON configuration
+- Formatting PICT output as markdown tables
+- Parsing PICT output into JSON
+
+**Installation:**
+```bash
+pip install pypict --break-system-packages
+```
+
+**Usage:**
+
+1. **Generate PICT model from config:**
+ ```bash
+ python pict_helper.py generate config.json > model.txt
+ ```
+
+2. **Format PICT output as markdown:**
+ ```bash
+ python pict_helper.py format output.txt
+ ```
+
+3. **Parse PICT output to JSON:**
+ ```bash
+ python pict_helper.py parse output.txt
+ ```
+
+**Example config.json:**
+```json
+{
+ "parameters": {
+ "Browser": ["Chrome", "Firefox", "Safari"],
+ "OS": ["Windows", "MacOS", "Linux"],
+ "Memory": ["4GB", "8GB", "16GB"]
+ },
+ "constraints": [
+ "IF [OS] = \"MacOS\" THEN [Browser] <> \"IE\"",
+ "IF [Memory] = \"4GB\" THEN [OS] <> \"MacOS\""
+ ]
+}
+```
+
+## Future Scripts
+
+We welcome contributions for:
+- Test automation generators
+- Export to test management tools (JIRA, TestRail)
+- Integration with CI/CD pipelines
+- Coverage analysis tools
+- Constraint validation utilities
+
+## Contributing
+
+Have a useful script to share?
+
+1. Add your script to this directory
+2. Update this README with usage instructions
+3. Add comments and examples in your script
+4. Submit a pull request
+
+See [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.
+
+## Dependencies
+
+Current scripts use:
+- Python 3.7+
+- pypict (optional, for direct PICT integration)
+
+All dependencies should be clearly documented in each script.
diff --git a/pairwise-tests/scripts/pict_helper.py b/pairwise-tests/scripts/pict_helper.py
new file mode 100644
index 0000000..3a64f91
--- /dev/null
+++ b/pairwise-tests/scripts/pict_helper.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python3
+"""
+PICT Helper Script
+
+This script provides utilities for working with PICT models and test cases.
+
+Note: This is a placeholder/example script. Full implementation coming soon!
+
+Requirements:
+ pip install pypict --break-system-packages
+
+Usage:
+ python pict_helper.py generate config.json
+ python pict_helper.py format output.txt
+ python pict_helper.py parse output.txt
+"""
+
+import sys
+import json
+from typing import Dict, List, Any
+
+def generate_model(config_file: str) -> str:
+ """
+ Generate a PICT model from a JSON configuration file.
+
+ Args:
+ config_file: Path to JSON config file
+
+ Returns:
+ PICT model as string
+
+ Example config.json:
+ {
+ "parameters": {
+ "Browser": ["Chrome", "Firefox", "Safari"],
+ "OS": ["Windows", "MacOS", "Linux"],
+ "Memory": ["4GB", "8GB", "16GB"]
+ },
+ "constraints": [
+ "IF [OS] = \"MacOS\" THEN [Browser] <> \"IE\"",
+ "IF [Memory] = \"4GB\" THEN [OS] <> \"MacOS\""
+ ]
+ }
+ """
+ try:
+ with open(config_file, 'r') as f:
+ config = json.load(f)
+
+ parameters = config.get('parameters', {})
+ constraints = config.get('constraints', [])
+
+ # Generate model
+ model_lines = []
+ model_lines.append("# Generated PICT Model")
+ model_lines.append("")
+
+ # Add parameters
+ for param_name, values in parameters.items():
+ values_str = ", ".join(values)
+ model_lines.append(f"{param_name}: {values_str}")
+
+ # Add constraints
+ if constraints:
+ model_lines.append("")
+ model_lines.append("# Constraints")
+ for constraint in constraints:
+ if not constraint.endswith(';'):
+ constraint += ';'
+ model_lines.append(constraint)
+
+ return "\n".join(model_lines)
+
+ except Exception as e:
+ print(f"Error generating model: {e}", file=sys.stderr)
+ return ""
+
+def format_output(output_file: str) -> str:
+ """
+ Format PICT output as a markdown table.
+
+ Args:
+ output_file: Path to PICT output file
+
+ Returns:
+ Markdown formatted table
+ """
+ try:
+ with open(output_file, 'r') as f:
+ lines = f.readlines()
+
+ if not lines:
+ return "No output to format"
+
+ # First line is header
+ header = lines[0].strip().split('\t')
+
+ # Create markdown table
+ table = []
+ table.append("| " + " | ".join(header) + " |")
+ table.append("|" + "|".join(["-" * (len(h) + 2) for h in header]) + "|")
+
+ # Add data rows
+ for line in lines[1:]:
+ if line.strip():
+ values = line.strip().split('\t')
+ table.append("| " + " | ".join(values) + " |")
+
+ return "\n".join(table)
+
+ except Exception as e:
+ print(f"Error formatting output: {e}", file=sys.stderr)
+ return ""
+
+def parse_output(output_file: str) -> List[Dict[str, str]]:
+ """
+ Parse PICT output into a list of dictionaries.
+
+ Args:
+ output_file: Path to PICT output file
+
+ Returns:
+ List of test case dictionaries
+ """
+ try:
+ with open(output_file, 'r') as f:
+ lines = f.readlines()
+
+ if not lines:
+ return []
+
+ # First line is header
+ header = lines[0].strip().split('\t')
+
+ # Parse data rows
+ test_cases = []
+ for i, line in enumerate(lines[1:], 1):
+ if line.strip():
+ values = line.strip().split('\t')
+ test_case = {"test_id": i}
+ for h, v in zip(header, values):
+ test_case[h] = v
+ test_cases.append(test_case)
+
+ return test_cases
+
+ except Exception as e:
+ print(f"Error parsing output: {e}", file=sys.stderr)
+ return []
+
+def main():
+ """Main entry point for the script."""
+ if len(sys.argv) < 2:
+ print("Usage:")
+ print(" python pict_helper.py generate <config.json>")
+ print(" python pict_helper.py format <output.txt>")
+ print(" python pict_helper.py parse <output.txt>")
+ sys.exit(1)
+
+ command = sys.argv[1]
+
+ if command == "generate" and len(sys.argv) >= 3:
+ config_file = sys.argv[2]
+ model = generate_model(config_file)
+ print(model)
+
+ elif command == "format" and len(sys.argv) >= 3:
+ output_file = sys.argv[2]
+ table = format_output(output_file)
+ print(table)
+
+ elif command == "parse" and len(sys.argv) >= 3:
+ output_file = sys.argv[2]
+ test_cases = parse_output(output_file)
+ print(json.dumps(test_cases, indent=2))
+
+ else:
+ print(f"Unknown command: {command}", file=sys.stderr)
+ sys.exit(1)
+
+if __name__ == "__main__":
+ main()
+
+# Example usage:
+"""
+# 1. Create a config.json file:
+{
+ "parameters": {
+ "Browser": ["Chrome", "Firefox", "Safari"],
+ "OS": ["Windows", "MacOS", "Linux"]
+ },
+ "constraints": [
+ "IF [OS] = \"MacOS\" THEN [Browser] <> \"IE\""
+ ]
+}
+
+# 2. Generate PICT model:
+python pict_helper.py generate config.json > model.txt
+
+# 3. Run PICT (if installed):
+pict model.txt > output.txt
+
+# 4. Format as markdown:
+python pict_helper.py format output.txt
+
+# 5. Parse to JSON:
+python pict_helper.py parse output.txt
+"""