Getting StartedTemplate Engine

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.id or $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

RoleResponsibilityTime Investment
DeveloperWrite the complex logic once as a generator function10-30 minutes
QACall the function with parameters10 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:

  1. Call developer-provided functions (the main use case)

    js: $gen.calculateOrderTotal($context.order, { tax: 0.2 });
  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 NeedToolWho Writes ItExample
Get a value from responseJSONataQAbody.user.id
Count/filter simple dataJSONataQA$count(body.orders)
Complex calculation/transformationJS + GeneratorDeveloper writes, QA callsjs:$gen.calculateTotal($context.order)
Quick timestamp/randomJS expressionQAjs: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:

  1. QA describes the logic needed in plain language
  2. AI generates the function code
  3. QA tests it with real data in the UI
  4. 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() - 3600000

All three levels are no-code—they’re about invoking capabilities, not creating them.

Quick Decision Tree for QA

  1. Simple value or path? → Use JSONata

    • Example: body.user.id, $count(body.orders)
  2. 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
  3. Quick timestamp or random value? → Use JS expression

    • Example: js:Date.now() - 3600000

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

  1. 90% of testing needs simple JSONata paths—pure no-code, no learning curve
  2. Complex logic = developer creates a function once—QA calls it hundreds of times
  3. js:$gen.functionName() is not coding—it’s function invocation (like Excel formulas)
  4. QA-first means QA never struggles—when it gets hard, developers provide tools
  5. 0-code = 0 complex logic—not literally zero characters typed
  6. 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.