본문으로 건너뛰기
cccskills
무료GitHub에 공개

qe-n8n-expression-testing

n8n expression syntax validation, context-aware testing, common pitfalls detection, and performance optimization. Use when validating n8n expressions and data transformations.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

proffesor-for-testing/agentic-qe스타 515(GitHub 515 + cccskills 0)
연동 도구n8n

실행 점수 미검증

설치 방법 보기

포함된 파일(1)

  • SKILL.md10.6 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

n8n Expression Testing

<default_to_action> When testing n8n expressions:

  1. VALIDATE syntax before execution
  2. TEST with multiple context scenarios
  3. CHECK for null/undefined handling
  4. VERIFY type safety
  5. SCAN for security vulnerabilities

Quick Expression Checklist:

  • Valid JavaScript syntax
  • Context variables properly referenced ($json, $node)
  • Null-safe access patterns (?., ??)
  • No dangerous functions (eval, Function)
  • Efficient for large data sets

Common Pitfalls:

  • Accessing nested properties without null checks
  • Type coercion issues
  • Missing fallback values
  • Inefficient array operations </default_to_action>

Quick Reference Card

n8n Expression Syntax

PatternExampleDescription
Basic access{{ $json.field }}Access JSON field
Nested access{{ $json.user.email }}Access nested property
Array access{{ $json.items[0] }}Access array element
Node reference{{ $node["Name"].json.id }}Access other node's data
Method call{{ $json.name.toLowerCase() }}Call string method
Conditional{{ $json.x ? "yes" : "no" }}Ternary expression

Context Variables

VariableDescriptionExample
$jsonCurrent item data{{ $json.email }}
$node["Name"]Other node's data{{ $node["HTTP"].json.body }}
$items()Multiple items{{ $items("Node", 0, 0).json }}
$nowCurrent timestamp{{ $now.toISO() }}
$todayToday's date{{ $today }}
$runIndexRun iteration{{ $runIndex }}
$workflowWorkflow info{{ $workflow.name }}

Expression Syntax Patterns

Safe Data Access

// BAD: Can fail if nested objects are null
{{ $json.user.profile.email }}

// GOOD: Optional chaining with fallback
{{ $json.user?.profile?.email ?? '' }}

// BAD: Array access without bounds check
{{ $json.items[0].name }}

// GOOD: Safe array access
{{ $json.items?.[0]?.name ?? 'No items' }}

Type Conversions

// String to Number
{{ parseInt($json.quantity, 10) }}
{{ parseFloat($json.price) }}
{{ Number($json.value) }}

// Number to String
{{ String($json.id) }}
{{ $json.amount.toString() }}
{{ $json.count.toFixed(2) }}

// Date handling
{{ new Date($json.timestamp).toISOString() }}
{{ DateTime.fromISO($json.date).toFormat('yyyy-MM-dd') }}

// Boolean conversion
{{ Boolean($json.active) }}
{{ $json.enabled === 'true' }}

String Operations

// Case conversion
{{ $json.name.toLowerCase() }}
{{ $json.name.toUpperCase() }}
{{ $json.name.charAt(0).toUpperCase() + $json.name.slice(1) }}

// String manipulation
{{ $json.text.trim() }}
{{ $json.text.replace(/\s+/g, ' ') }}
{{ $json.text.substring(0, 100) }}

// Template strings
{{ `Hello, ${$json.firstName} ${$json.lastName}!` }}
{{ `Order #${$json.orderId} - ${$json.status}` }}

Array Operations

// Mapping
{{ $json.items.map(item => item.name) }}
{{ $json.items.map(item => ({ id: item.id, total: item.price * item.qty })) }}

// Filtering
{{ $json.items.filter(item => item.active) }}
{{ $json.items.filter(item => item.price > 100) }}

// Reducing
{{ $json.items.reduce((sum, item) => sum + item.price, 0) }}
{{ $json.items.reduce((acc, item) => ({ ...acc, [item.id]: item }), {}) }}

// Finding
{{ $json.items.find(item => item.id === $json.targetId) }}
{{ $json.items.findIndex(item => item.name === 'target') }}

// Joining
{{ $json.tags.join(', ') }}
{{ $json.items.map(i => i.name).join(' | ') }}

Validation Patterns

// Validate expression syntax
function validateExpressionSyntax(expression: string): ValidationResult {
  // Remove n8n template markers
  const code = expression.replace(/\{\{|\}\}/g, '').trim();

  try {
    // Check if valid JavaScript
    new Function(`return (${code})`);
    return { valid: true };
  } catch (error) {
    return {
      valid: false,
      error: error.message,
      suggestion: suggestFix(error.message, code)
    };
  }
}

// Validate context variables
function validateContextVariables(expression: string): string[] {
  const contextVars = ['$json', '$node', '$items', '$now', '$today', '$runIndex', '$workflow'];
  const usedVars = [];
  const invalidVars = [];

  // Find all $ prefixed variables
  const varPattern = /\$\w+/g;
  let match;

  while ((match = varPattern.exec(expression)) !== null) {
    const varName = match[0];
    if (contextVars.some(cv => varName.startsWith(cv))) {
      usedVars.push(varName);
    } else {
      invalidVars.push(varName);
    }
  }

  return { usedVars, invalidVars };
}

// Test expression with sample data
function testExpression(expression: string, context: any): TestResult {
  const code = expression.replace(/\{\{|\}\}/g, '').trim();

  try {
    // Create function with context
    const fn = new Function('$json', '$node', '$items', '$now', '$today',
      `return (${code})`);

    const result = fn(
      context.$json || {},
      context.$node || {},
      context.$items || (() => ({})),
      context.$now || new Date(),
      context.$today || new Date()
    );

    return { success: true, result };
  } catch (error) {
    return { success: false, error: error.message };
  }
}

Common Errors and Fixes

Undefined Property Access

// ERROR: Cannot read property 'email' of undefined
{{ $json.user.email }}

// FIX 1: Optional chaining
{{ $json.user?.email }}

// FIX 2: With fallback
{{ $json.user?.email ?? 'no-email@example.com' }}

// FIX 3: Conditional
{{ $json.user ? $json.user.email : '' }}

Type Errors

// ERROR: toLowerCase is not a function (when null)
{{ $json.name.toLowerCase() }}

// FIX: Null check first
{{ $json.name?.toLowerCase() ?? '' }}

// ERROR: toFixed is not a function (string instead of number)
{{ $json.price.toFixed(2) }}

// FIX: Parse as number first
{{ parseFloat($json.price).toFixed(2) }}

// ERROR: map is not a function (not an array)
{{ $json.items.map(i => i.name) }}

// FIX: Ensure array
{{ (Array.isArray($json.items) ? $json.items : []).map(i => i.name) }}

Node Reference Errors

// ERROR: Node "Previous Node" not found
{{ $node["Previous Node"].json.data }}

// FIX: Use exact node name (case-sensitive)
{{ $node["Previous Node1"].json.data }}

// FIX: Add fallback for safety
{{ $node["Previous Node"]?.json?.data ?? {} }}

Security Patterns

Dangerous Functions to Avoid

// DANGEROUS: Never use eval
{{ eval($json.code) }}

// DANGEROUS: Dynamic function creation
{{ new Function($json.code)() }}

// DANGEROUS: setTimeout with string
{{ setTimeout($json.code, 1000) }}

// SAFE: Use explicit operations instead
{{ $json.value * 2 }}
{{ JSON.parse($json.jsonString) }}

Input Validation

// Validate email format
{{ /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test($json.email) ? $json.email : '' }}

// Sanitize for HTML (basic)
{{ $json.text.replace(/[<>&"']/g, c => ({
  '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;', "'": '&#39;'
}[c])) }}

// Limit string length
{{ $json.input.substring(0, 1000) }}

// Validate number range
{{ Math.min(Math.max(parseInt($json.value), 0), 100) }}

Performance Optimization

Efficient Array Operations

// SLOW: Multiple iterations
{{ $json.items.filter(i => i.active).map(i => i.name).join(', ') }}

// FASTER: Single reduce
{{ $json.items.reduce((acc, i) => i.active ? (acc ? `${acc}, ${i.name}` : i.name) : acc, '') }}

// SLOW: Nested loops
{{ $json.items.map(i => $json.categories.find(c => c.id === i.categoryId)) }}

// FASTER: Create lookup map first (in Code node)
const categoryMap = Object.fromEntries($json.categories.map(c => [c.id, c]));
return $json.items.map(i => categoryMap[i.categoryId]);

Avoid in Expressions

// AVOID: Complex logic in expressions
{{ $json.items.reduce((acc, item) => {
  const category = $json.categories.find(c => c.id === item.catId);
  if (category && category.active) {
    acc.push({ ...item, categoryName: category.name });
  }
  return acc;
}, []) }}

// BETTER: Move to Code node for complex transformations

Testing Patterns

// Expression test suite
const expressionTests = [
  {
    name: 'Basic property access',
    expression: '{{ $json.name }}',
    context: { $json: { name: 'John' } },
    expected: 'John'
  },
  {
    name: 'Nested with optional chaining',
    expression: '{{ $json.user?.email ?? "default" }}',
    context: { $json: { user: null } },
    expected: 'default'
  },
  {
    name: 'Array mapping',
    expression: '{{ $json.items.map(i => i.id).join(",") }}',
    context: { $json: { items: [{ id: 1 }, { id: 2 }] } },
    expected: '1,2'
  },
  {
    name: 'Conditional expression',
    expression: '{{ $json.score >= 70 ? "Pass" : "Fail" }}',
    context: { $json: { score: 85 } },
    expected: 'Pass'
  },
  {
    name: 'Node reference',
    expression: '{{ $node["Previous"].json.result }}',
    context: { $node: { Previous: { json: { result: 'success' } } } },
    expected: 'success'
  }
];

// Run tests
for (const test of expressionTests) {
  const result = testExpression(test.expression, test.context);
  console.log(`${test.name}: ${result.result === test.expected ? 'PASS' : 'FAIL'}`);
}

Agent Coordination

Memory Namespace

aqe/n8n/expressions/
├── validations/*    - Expression validation results
├── patterns/*       - Discovered expression patterns
├── errors/*         - Common error catalog
└── optimizations/*  - Performance suggestions

Fleet Coordination

// Coordinate expression validation with workflow testing
await Task("Validate expressions", {
  workflowId: "wf-123",
  validateAll: true,
  testWithSampleData: true
}, "n8n-expression-validator");

Related Skills


Remember

n8n expressions are JavaScript-like with special context variables ($json, $node, etc.). Testing requires:

  • Syntax validation
  • Context variable verification
  • Null safety checks
  • Type compatibility
  • Security scanning

Key patterns: Use optional chaining (?.) and nullish coalescing (??) for safety. Move complex logic to Code nodes. Always test with edge cases (null, undefined, empty arrays).

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

a11y-ally

무료

Use when running comprehensive WCAG accessibility audits with axe-core + pa11y + Lighthouse, generating context-aware remediation, or testing video accessibility. Supports 3-tier browser cascade with graceful degradation.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

proffesor-for-testing/agentic-qe5152026년 10월 26일 업데이트

WCAG 2.2 compliance testing, screen reader validation, and inclusive design verification. Use when ensuring legal compliance (ADA, Section 508), testing for disabilities, or building accessible applications for 1 billion disabled users globally.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

proffesor-for-testing/agentic-qe5152026년 10월 26일 업데이트

Master advanced AgentDB features including QUIC synchronization, multi-database management, custom distance metrics, hybrid search, and distributed systems integration. Use when building distributed AI systems, multi-agent coordination, or advanced vector search applications.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

proffesor-for-testing/agentic-qe5152026년 10월 26일 업데이트

Create and train AI learning plugins with AgentDB's 9 reinforcement learning algorithms. Includes Decision Transformer, Q-Learning, SARSA, Actor-Critic, and more. Use when building self-learning agents, implementing RL, or optimizing agent behavior through experience.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

proffesor-for-testing/agentic-qe5152026년 10월 26일 업데이트

Implement persistent memory patterns for AI agents using AgentDB. Includes session memory, long-term storage, pattern learning, and context management. Use when building stateful agents, chat systems, or intelligent assistants.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

proffesor-for-testing/agentic-qe5152026년 10월 26일 업데이트

Optimize AgentDB performance with quantization (4-32x memory reduction), HNSW indexing (150x faster search), caching, and batch operations. Use when optimizing memory usage, improving search speed, or scaling to millions of vectors.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

proffesor-for-testing/agentic-qe5152026년 10월 26일 업데이트

proffesor-for-testing의 스킬 모두 보기

이 스킬의 문제 신고