Expressions for API Testing: No-Code to Low-Code
ReAPI’s expression system is designed around a clear principle: QA engineers should never write complex logic. Instead, they work at the right level of abstraction for their needs—from simple data paths to calling developer-provided functions.
What “No-Code” Really Means
No-code doesn’t mean zero characters—it means zero complex logic. Just like:
- Using Excel formulas (
=SUM(A1:A10)) isn’t “coding” - Writing SQL queries (
SELECT * FROM users) isn’t “coding” - Calling a function (
calculateTotal(order)) isn’t “coding”
No-code means: QA focuses on what to test, developers handle how to compute.
The 90/10 Rule
- 90% of scenarios: Simple JSONata paths like
body.user.idor$count(body.orders)→ Pure no-code - 10% complex scenarios: Call a developer-provided function → Still no-code (just function invocation)
When logic gets complex, don’t write it yourself—call someone who already wrote it for you.
Level 1: JSONata for 90% of Scenarios
In any field that accepts expressions (Assertions, Context modifications, loop conditions), JSONata is the default mode—no prefix required.
Perfect for QA: Simple, Readable, No-Code
Common scenarios (all no programming required):
- Access a value:
body.user.id - Check array length:
$count(body.orders) - Filter simple conditions:
body.users[age > 18] - Get nested data:
response.data.metrics.totalRevenue
This is truly no-code—just paths and simple queries. Handles 90% of real-world test assertions.
📖 Deep Dive: To master data querying, please refer to our dedicated JSONata Expression Language guide.
⚠️ When to Stop Using JSONata
If you see yourself using JSONata’s advanced functions like $map(), $reduce(), $filter() with complex logic—STOP.
Example of what NOT to do (QA shouldn’t write this):
$map(body.orders, function($order) {
$merge([$order, {"total": $sum($order.items.price)}])
})This is complex logic. At this point, ask a developer for help instead of struggling with JSONata syntax.
Level 2: Call Developer-Provided Functions (Still No-Code!)
When a scenario needs complex transformation or calculation, developers write a reusable function once, and QA calls it everywhere.
The Empowerment Model
| Role | Responsibility | Time Investment |
|---|---|---|
| Developer | Write the complex logic once as a generator function | 10-30 minutes |
| QA | Call the function with parameters | 10 seconds |
QA learns: js:$gen.functionName(parameters)
That’s it. No loops, no conditions, no complex logic—just function invocation.
Real-World Example: Complex Order Calculation
Scenario: Assert that the calculated order total matches expected value with tax, shipping, and discounts.
Without ReAPI (QA writes complex logic):
// QA has to understand and write this everywhere:
const subtotal = order.items.reduce(
(sum, item) => sum + item.price * item.qty,
0
);
const discount = subtotal * order.discountRate;
const tax = (subtotal - discount) * 0.2;
const total = subtotal - discount + tax + order.shipping;With ReAPI (Developer writes once, QA calls it):
// Developer writes function once (10 minutes):
async function calculateOrderTotal(order, options) {
// ... all the complex logic ...
return total;
}
// QA uses it everywhere (10 seconds):
js: $gen.calculateOrderTotal($context.order, { includeShipping: true });Is $gen.calculateOrderTotal() coding? No more than =SUM(A1:A10) is coding in Excel. It’s function invocation, not function creation.
JavaScript Expressions: Two Simple Use Cases
Use Case 1: Building Dynamic API Requests
When constructing API request URL, headers, or body, use template syntax:
{{variable}}→ Insert context variable:{{userId}}${expression}→ Call built-in functions:${faker.internet.email()}
Example Request Body:
{
"email": "${faker.internet.email()}",
"userId": "{{currentUserId}}",
"timestamp": "${Date.now()}"
}Use Case 2: Calling Functions in Expressions (js:)
In expression fields (assertions, context updates), use js: prefix to:
-
Call developer-provided functions (the main use case)
js: $gen.calculateOrderTotal($context.order, { tax: 0.2 }); -
Simple one-off calculations (when a function doesn’t exist yet)
js: Date.now() - 3600000; // One hour ago
QA is NOT writing complex logic—either calling existing functions or doing trivial calculations.
Quick Reference: What Tool When
| What You Need | Tool | Who Writes It | Example |
|---|---|---|---|
| Get a value from response | JSONata | QA | body.user.id |
| Count/filter simple data | JSONata | QA | $count(body.orders) |
| Complex calculation/transformation | JS + Generator | Developer writes, QA calls | js:$gen.calculateTotal($context.order) |
| Quick timestamp/random | JS expression | QA | js:Date.now() - 3600000 |
The Golden Rule
If you need `$map()`, `$reduce()`, or complex logic:
❌ Don't write it in JSONata
❌ Don't write it in JS expression
✅ Ask developer to create a generator function
✅ You just call it: js:$gen.functionName(params)Why This Model Is Powerful
1. QA Independence
90% of scenarios: Pure no-code with JSONata paths
10% complex scenarios: Call pre-built functions (still no-code)
QA can test complex business logic without understanding the implementation.
2. Developer Leverage
Developer spends 10-30 minutes writing a function → QA team uses it hundreds of times across thousands of tests.
ROI Example:
- Developer effort: 30 minutes to write
calculateOrderTotal() - QA usage: 200 tests × 10 seconds each = 33 minutes
- Without this: QA would need developer help 200 times or copy-paste buggy logic
3. Maintainability
When business logic changes (e.g., tax rate calculation), developer updates one function—all tests automatically adapt.
4. The AI Multiplier Effect
Current reality: ChatGPT and similar AI tools can already generate medium-complexity pure functions if you describe:
- Input parameters
- Expected output
- Business rules
QA with basic understanding can get AI-generated functions without waiting for developers.
Near future: ReAPI’s AI Agent will integrate this directly:
- QA describes the logic needed in plain language
- AI generates the function code
- QA tests it with real data in the UI
- If it works, save it; if not, refine the description
The key insight: This is still AI coding, not QA coding. QA remains in the requirement + validation role, never in the implementation role.
Why developers are still valuable:
- Better requirement abstraction for reusability
- Edge case handling from experience
- Long-term API design for maintainability
But for ambitious QA engineers: AI lowers the barrier without requiring you to become a programmer.
5. It’s Still “QA-First”
QA-first doesn’t mean “QA can only click buttons”. It means:
- QA should never struggle with complex logic
- When complexity arises, developers provide tools
- QA focuses on what to test, not how to compute
Calling $gen.calculateOrderTotal() is the same level as:
- Using Excel’s
=VLOOKUP() - Writing SQL
SELECT * FROM users WHERE age > 18 - Clicking a UI button
It’s invocation, not coding.
Summary: The QA-First Expression Model
Three Levels for QA
Level 1 (90%): JSONata paths → body.user.id
Level 2 (9%): Call generator funcs → js:$gen.calculateTotal(order)
Level 3 (1%): One-off expressions → js:Date.now() - 3600000All three levels are no-code—they’re about invoking capabilities, not creating them.
Quick Decision Tree for QA
-
Simple value or path? → Use JSONata
- Example:
body.user.id,$count(body.orders)
- Example:
-
Complex calculation needed? → Call a generator function
- Example:
js:$gen.calculateOrderTotal($context.order, { tax: 0.2 }) - If function doesn’t exist: Ask developer to create one
- Example:
-
Quick timestamp or random value? → Use JS expression
- Example:
js:Date.now() - 3600000
- Example:
Never write $map(), $reduce(), or complex logic yourself—that’s when you ask for developer help.
For Developers: Empower QA
When QA asks “How do I calculate X?”, don’t explain the logic—write a generator function:
// 10 minutes of your time
async function calculateComplexMetric(data, options) {
// All the complex logic here
return result;
}
// QA uses it 200 times:
js: $gen.calculateComplexMetric($context.data, { mode: "full" });This is the empowerment model: Minimal developer time, maximum QA capability.
The AI Advantage (Coming Soon)
Here’s an exciting development: AI can write pure functions for you.
For medium-complexity logic, tools like ChatGPT can easily generate the function if you describe:
- What data you have (parameters)
- What result you need (output)
- Any business rules to apply
Example prompt to AI:
“Write a JavaScript function that takes an order object with items array, each with price and quantity. Calculate subtotal, apply a discount rate, add 20% tax, and include shipping. Return the total.”
ChatGPT generates the function in seconds. QA can copy it into ReAPI without needing developer help.
Why we still recommend involving developers:
- Developers understand how to abstract requirements for maximum reusability
- They know what edge cases to handle
- They design better parameter APIs for long-term maintenance
But for ambitious QA engineers: ReAPI’s upcoming AI Agent will help you create functions directly in the UI—describe what you need, AI writes it, you test it, done.
Important: It’s the AI doing the coding, not you. You’re describing requirements and testing results—still no programming required.
What “No-Code” Really Means
- ✅ No-code: Path queries (
body.user.id), function calls ($gen.calc()) - ❌ Not no-code: Writing
$map(),$reduce(), complex transformations
Analogy:
- Excel user writes
=VLOOKUP()→ No-code (function invocation) - Excel user writes VBA macros → Coding (function creation)
ReAPI QA stays at the invocation level, developers handle the creation level.
Key Takeaways
- 90% of testing needs simple JSONata paths—pure no-code, no learning curve
- Complex logic = developer creates a function once—QA calls it hundreds of times
js:$gen.functionName()is not coding—it’s function invocation (like Excel formulas)- QA-first means QA never struggles—when it gets hard, developers provide tools
- 0-code = 0 complex logic—not literally zero characters typed
- AI agents are coming—describe what you need, AI writes the function, you test it (AI codes, not you)
The model works because:
- Developers invest 10-30 minutes → QA gains infinite reusability
- Business logic lives in one place → all tests adapt automatically
- QA focuses on test scenarios → developers handle implementation details
- AI agents amplify this further—ambitious QA can leverage AI without becoming programmers
This is how ReAPI scales testing from simple API calls to complex business logic validation—without turning QA into programmers.