assertion-synthesizer
Generate test assertions from existing code implementation. Use when the user has implementation code without tests or incomplete test coverage, and needs assertions synthesized by analyzing the code's behavior, inputs, outputs, and state changes. Supports Python (pytest/unittest), Java (JUnit/AssertJ), and JavaScript/TypeScript (Jest/Chai). Handles equality checks, collections, exceptions, and state verification.
git clone --depth 1 https://github.com/ArabelaTso/Skills-4-SE /tmp/assertion-synthesizer && cp -r /tmp/assertion-synthesizer/skills/assertion-synthesizer ~/.claude/skills/assertion-synthesizerSKILL.md
# Assertion Synthesizer
Generate comprehensive test assertions by analyzing code implementation, behavior, and expected outputs.
## Workflow
### 1. Analyze Code
Read and understand the implementation to identify testable behavior:
- **Function signatures**: Parameters, return types, side effects
- **Logic paths**: Conditionals, loops, branching behavior
- **Edge cases**: Boundary conditions, null/empty inputs, error conditions
- **State changes**: Object mutations, attribute modifications
- **Dependencies**: External calls, database operations, I/O
### 2. Identify Test Scenarios
Extract scenarios that need assertions:
- **Happy path**: Normal inputs producing expected outputs
- **Edge cases**: Empty lists, zero values, boundary conditions
- **Error cases**: Invalid inputs, exceptions, error handling
- **State verification**: Object state before/after operations
- **Collection assertions**: List contents, ordering, membership
### 3. Generate Assertions
Create appropriate assertions for each scenario:
**Assertion Types:**
- **Equality**: `assert result == expected`, `assertEquals(expected, actual)`
- **Truthiness**: `assert is_valid`, `assertTrue(condition)`
- **Collections**: `assert item in list`, `assertContains(list, item)`
- **Exceptions**: `pytest.raises(Exception)`, `assertThrows(Exception)`
- **State**: `assert obj.status == "active"`, `assertEquals("active", obj.getStatus())`
### 4. Structure Tests
Organize assertions into well-structured test functions:
- Use descriptive test names
- Follow Arrange-Act-Assert pattern
- Group related assertions
- Add explanatory comments
### 5. Verify Coverage
Ensure all important behaviors have assertions:
- Check all return values are tested
- Verify edge cases are covered
- Confirm error conditions are tested
- Validate state changes are asserted
## Language-Specific Patterns
### Python (pytest)
```python
def test_basic_equality():
# Arrange
calculator = Calculator()
# Act
result = calculator.add(2, 3)
# Assert
assert result == 5
def test_collection_membership():
items = get_active_items()
assert "item1" in items
assert len(items) == 3
def test_exception_handling():
with pytest.raises(ValueError, match="Invalid input"):
process_data(None)
def test_state_change():
user = User("Alice")
user.activate()
assert user.is_active == True
assert user.status == "active"
```
### Python (unittest)
```python
def test_basic_equality(self):
calculator = Calculator()
result = calculator.add(2, 3)
self.assertEqual(result, 5)
def test_collection_membership(self):
items = get_active_items()
self.assertIn("item1", items)
self.assertEqual(len(items), 3)
def test_exception_handling(self):
with self.assertRaises(ValueError):
process_data(None)
def test_state_change(self):
user = User("Alice")
user.activate()
self.assertTrue(user.is_active)
self.assertEqual(user.status, "active")
```
### Java (JUnit + AssertJ)
```java
@Test
void testBasicEquality() {
Calculator calculator = new Calculator();
int result = calculator.add(2, 3);
assertThat(result).isEqualTo(5);
}
@Test
void testCollectionMembership() {
List<String> items = getActiveItems();
assertThat(items).contains("item1");
assertThat(items).hasSize(3);
}
@Test
void testExceptionHandling() {
assertThatThrownBy(() -> processData(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid input");
}
@Test
void testStateChange() {
User user = new User("Alice");
user.activate();
assertThat(user.isActive()).isTrue();
assertThat(user.getStatus()).isEqualTo("active");
}
```
### JavaScript/TypeScript (Jest)
```javascript
test('basic equality', () => {
const calculator = new Calculator();
const result = calculator.add(2, 3);
expect(result).toBe(5);
});
test('collection membership', () => {
const items = getActiveItems();
expect(items).toContain('item1');
expect(items).toHaveLength(3);
});
test('exception handling', () => {
expect(() => processData(null))
.toThrow('Invalid input');
});
test('state change', () => {
const user = new User('Alice');
user.activate();
expect(user.isActive).toBe(true);
expect(user.status).toBe('active');
});
```
## Assertion Synthesis Strategies
### From Return Values
Analyze what the function returns and assert on it:
```python
# Code:
def get_full_name(first, last):
return f"{first} {last}"
# Synthesized assertion:
def test_get_full_name():
result = get_full_name("John", "Doe")
assert result == "John Doe"
assert isinstance(result, str)
```
### From Side Effects
Identify state changes and mutations:
```python
# Code:
def withdraw(account, amount):
if account.balance >= amount:
account.balance -= amount
return True
return False
# Synthesized assertions:
def test_withdraw_success():
account = Account(balance=100)
result = withdraw(account, 50)
assert result == True
assert account.balance == 50
def test_withdraw_insufficient_funds():
account = Account(balance=30)
result = withdraw(account, 50)
assert result == False
assert account.balance == 30 # Balance unchanged
```
### From Conditional Logic
Test each branch:
```python
# Code:
def classify_age(age):
if age < 0:
raise ValueError("Invalid age")
elif age < 18:
return "minor"
elif age < 65:
return "adult"
else:
return "senior"
# Synthesized assertions:
def test_classify_age_invalid():
with pytest.raises(ValueError):
classify_age(-1)
def test_classify_age_minor():
assert classify_age(10) == "minor"
assert classify_age(17) == "minor"
def test_classify_age_adult():
assert classify_age(18) == "adult"
assert classify_age(64) == "adult"
def test_classify_age_senior():
assert classify_age(65) == "senior"
assert clApplies abstract interpretation using different abstract domains (intervals, octagons, polyhedra, sign, congruence) to statically analyze program variables and infer invariants, value ranges, and relationships. Use when analyzing program properties, inferring loop invariants, detecting potential errors, or understanding variable relationships through static analysis.
Uses abstract interpretation to automatically infer loop invariants, function preconditions, and postconditions for formal verification. Generates invariants that capture program behavior and support correctness proofs in Dafny, Isabelle, Coq, and other verification systems. Use when adding formal specifications to code, generating verification conditions, inferring contracts for functions, or discovering loop invariants for proofs.
Performs abstract interpretation over source code to infer possible program states, variable ranges, and data properties without executing the program. Reports potential runtime errors including out-of-bounds accesses, null dereferences, type inconsistencies, division by zero, and integer overflows. Use when analyzing code for potential runtime errors, performing static analysis, checking safety properties, or verifying program behavior without execution.
Performs abstract interpretation to produce summarized execution traces and high-level program behavior representations. Highlights key control flow paths, variable relationships, loop invariants, function summaries, and potential runtime states using abstract domains (intervals, signs, nullness, etc.). Use when analyzing program behavior, understanding execution paths, computing loop invariants, tracking variable ranges, detecting potential runtime errors, or generating program summaries without concrete execution.
Create ACSL (ANSI/ISO C Specification Language) formal annotations for C/C++ programs. Use this skill when working with formal verification, adding function contracts (requires/ensures), loop invariants, assertions, memory safety annotations, or any ACSL specifications. Supports Frama-C verification and generates comprehensive formal specifications for C/C++ code.
CLI-based browser automation with persistent page state using ref-based element interaction. Use when users ask to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
Detects and analyzes ambiguous language in software requirements and user stories. Use when reviewing requirements documents, user stories, specifications, or any software requirement text to identify vague quantifiers, unclear scope, undefined terms, missing edge cases, subjective language, and incomplete specifications. Provides detailed analysis with clarifying questions and suggested improvements.
Design and review APIs with suggestions for endpoints, parameters, return types, and best practices. Use when designing new APIs from requirements, reviewing existing API designs, generating API documentation, or getting implementation guidance. Supports REST APIs with focus on endpoint structure, request/response schemas, authentication, pagination, filtering, versioning, and OpenAPI specifications. Triggers when users ask to design, review, document, or improve APIs.