Obsah článku / Contents
Scout: Keď AI číta váš kód a píše testy za vás

Scout: Keď AI číta váš kód a píše testy za vás

Predstavte si toto: máte 50 komponentov s formulármi, tlačidlami a navigáciou. QA tím potrebuje testovacie scenáre. Developer hovorí "veď tam sú data-testid, stačí napísať testy". QA engineer vzdychne a začne manuálne prechádzať každý komponent.

Scout tento proces automatizuje: prečíta váš zdrojový kód a vygeneruje hotové Playwright testy.

Problém: Testy z kódu vs testy z UI

Existujú dva prístupy ku generovaniu testov:

Dynamická analýza (runtime)

Spustím aplikáciu → Prehľadám UI → Extrahujem elementy → Generujem testy

Výhoda: Vidí skutočný stav aplikácie Nevýhoda: Potrebuje bežiacu aplikáciu, je pomalšia

Statická analýza (source code)

Prečítam zdrojový kód → Analyzujem komponenty → Generujem testy

Výhoda: Nepotrebuje bežiacu aplikáciu, je rýchlejšia Nevýhoda: Nevidí runtime správanie

Scout používa statickú analýzu - číta váš kód a generuje testy priamo z neho. Ideálne pre:

  • CI/CD pipeline (nepotrebujete staging server)
  • Rýchle generovanie pri vývoji
  • Analýzu pred deploymentom

Čo Scout robí?

Scout má tri hlavné schopnosti:

1. ANALYZE  → Skenuje projekt, extrahuje formuláre, tlačidlá, linky
2. MARK     → Zavolá Marker service na pridanie data-testid
3. GENERATE → LLM vygeneruje testovacie scenáre

Výstup:

  • JSON scenáre (Sentinel-kompatibilné)
  • Python testy (Playwright + Pytest)

Príklad workflow

bash
# 1. Analyzuj projekt
python main.py analyze /path/to/frontend

# Výstup:
# Found 47 components
# - 12 forms with 38 input fields
# - 45 buttons (23 with click handlers)
# - 67 data-testid attributes
# - 15 navigation links

# 2. Vygeneruj scenáre
python main.py generate /path/to/frontend

# Výstup:
# Generated 156 test scenarios
# - 47 happy path scenarios
# - 62 validation scenarios
# - 31 navigation scenarios
# - 16 edge case scenarios

Ako Scout analyzuje kód?

Scout používa regex patterns na detekciu elementov v rôznych frameworkoch:

Angular detekcia

html
<!-- Scout rozpozná -->
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <input formControlName="email" [required]="true">
  <button type="submit" data-testid="btn-submit">Send</button>
</form>

<a routerLink="/about">About</a>

Extrahované informácie:

  • Form s formGroup "contactForm"
  • Input s formControlName "email" + required validácia
  • Button s data-testid "btn-submit"
  • RouterLink na "/about"

React/JSX detekcia

jsx
// Scout rozpozná
<form onSubmit={handleSubmit}>
  <input 
    type="email" 
    required 
    data-testid="input-email"
    onChange={(e) => setEmail(e.target.value)}
  />
  <button type="submit">Submit</button>
</form>

<Link to="/dashboard">Dashboard</Link>

Vue detekcia

vue
<!-- Scout rozpozná -->
<template>
  <form @submit.prevent="submitForm">
    <input v-model="email" required data-testid="input-email">
    <button type="submit">Odoslať</button>
  </form>
  
  <router-link :to="{ name: 'home' }">Home</router-link>
</template>

Inteligentné URL inference

Scout automaticky odvodí URL stránky z cesty súboru:

python
# Angular pattern
src/app/pages/contact/contact.component.html
→ URL: /contact

# Vue/Nuxt pattern
pages/about/index.vue
→ URL: /about

# React pattern
src/pages/Dashboard.tsx
→ URL: /dashboard

Toto umožňuje generovať testy s správnymi page.goto() volaniami.

Čo Scout vygeneruje?

1. Sentinel JSON formát

json
{
  "id": "contact-ecbaee-successful-form-submission-00",
  "name": "Successful form submission with valid data",
  "description": "Tests that the contact form can be submitted successfully",
  "page_url": "/contact",
  "steps": [
    {
      "action": "fill",
      "selector": "[data-testid=\"input-name\"]",
      "value": "John Doe",
      "description": "Fill name field"
    },
    {
      "action": "fill",
      "selector": "[data-testid=\"input-email\"]",
      "value": "john.doe@example.com",
      "description": "Fill email field with valid format"
    },
    {
      "action": "click",
      "selector": "[data-testid=\"btn-submit\"]",
      "value": "",
      "description": "Click submit button"
    },
    {
      "action": "verify_visible",
      "selector": ".success-message",
      "value": "",
      "description": "Verify success message appears"
    }
  ]
}

2. Playwright Python testy

python
import pytest
from playwright.sync_api import Page

def test_successful_form_submission_with_valid_data(page: Page, base_url: str):
    """Tests that the contact form can be submitted successfully"""
    page.goto(f"{base_url}/contact")
    
    # Fill name field
    page.locator("[data-testid=\"input-name\"]").fill("John Doe")
    
    # Fill email field with valid format
    page.locator("[data-testid=\"input-email\"]").fill("john.doe@example.com")
    
    # Click submit button
    page.locator("[data-testid=\"btn-submit\"]").click()
    
    # Verify success message appears
    expect(page.locator(".success-message")).to_be_visible()


def test_form_validation_required_fields(page: Page, base_url: str):
    """Tests that required field validation works correctly"""
    page.goto(f"{base_url}/contact")
    
    # Try to submit empty form
    page.locator("[data-testid=\"btn-submit\"]").click()
    
    # Verify validation errors appear
    expect(page.locator(".error-message")).to_be_visible()

Testy sú ihneď spustiteľné s pytest!

Typy generovaných scenárov

Scout generuje 4 kategórie testov:

1. Happy Path (úspešný priebeh)

python
def test_successful_login():
    # Vyplň správne údaje → očakávaj úspech

2. Validation Tests (validácia)

python
def test_email_format_validation():
    # Vyplň neplatný email → očakávaj error

def test_required_field_validation():
    # Nechaj povinné pole prázdne → očakávaj error

3. Navigation Tests (navigácia)

python
def test_navigation_to_about_page():
    # Klikni na link → over že si na správnej stránke

4. Edge Cases (hraničné prípady)

python
def test_form_with_special_characters():
    # Vyplň špeciálne znaky → over správanie

Scout rozumie validácii

Scout detekuje validačné pravidlá vo vašom kóde:

typescript
// Angular Reactive Forms
this.form = this.fb.group({
  email: ['', [Validators.required, Validators.email]],
  phone: ['', [Validators.pattern(/^\d{10}$/)]],
  age: ['', [Validators.min(18), Validators.max(100)]]
});

Scout vygeneruje testy pre:

  • ✅ Required field validation
  • ✅ Email format validation
  • ✅ Pattern matching validation
  • ✅ Min/max value validation
html
<!-- HTML5 validácia -->
<input type="email" required minlength="5" maxlength="100">

Scout rozpozná aj HTML5 atribúty a vygeneruje príslušné testy.

Architektúra Scout

┌─────────────────────────────────────────────────────┐
│                  User Interface                      │
│        CLI │ gRPC Server │ MCP Server               │
└──────────────────────┬──────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────┐
│                  CodeAnalyzer                        │
│   - Skenuje .html, .jsx, .tsx, .vue                 │
│   - Regex extrakcia formulárov, tlačidiel, linkov   │
│   - Detekcia validačných pravidiel                  │
│   - URL inference z cesty súboru                    │
└──────────────────────┬──────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────┐
│               ScenarioGenerator                      │
│   - Ollama + Qwen3-Coder LLM                        │
│   - Prompt building z analýzy                       │
│   - JSON parsing s error recovery                   │
│   - Generovanie unikátnych ID                       │
└──────────────────────┬──────────────────────────────┘
                       ↓
┌──────────────────┬──────────────────────────────────┐
│  Sentinel JSON   │      Playwright Tests            │
│  (scenáre)       │      (pytest)                    │
└──────────────────┴──────────────────────────────────┘

Integrácia s Marker

Scout môže zavolať Marker service na pridanie data-testid:

bash
# Spustite Marker gRPC server
cd ../marker && python grpc_server.py

# Scout pridá testid + vygeneruje scenáre
python main.py full /path/to/frontend

Workflow:

1. Scout analyzuje komponenty
2. Scout zavolá Marker → pridá data-testid
3. Scout znovu analyzuje (teraz s testid)
4. Scout vygeneruje scenáre

3 spôsoby použitia

1. CLI (Command Line)

bash
# Len analýza
python main.py analyze /path/to/frontend

# Len generovanie scenárov
python main.py generate /path/to/frontend --output ./tests

# Kompletný workflow
python main.py full /path/to/frontend

# S custom užívateľom pre multi-role testing
python main.py generate /path --user admin --role administrator

2. gRPC Server

bash
# Spustite server
python main.py grpc-server --port 50052

# Volajte z akéhokoľvek jazyka
# Service: ScoutService
# Methods: Analyze, Generate, FullWorkflow

3. MCP Server (Claude integrácia)

json
// claude_desktop_config.json
{
  "mcpServers": {
    "scout": {
      "command": "python",
      "args": ["main.py", "mcp-server"]
    }
  }
}

V Claude:

"Analyzuj môj Angular projekt a vygeneruj testy pre contact form"
→ Claude zavolá scout_analyze + scout_generate

Scout vs Sentinel: Kedy čo použiť?

AspektScoutSentinel
PrístupStatická analýza kóduDynamická analýza UI
PotrebujeZdrojový kódBežiacu aplikáciu
RýchlosťRýchlejšiePomalšie (naviguje UI)
PokrytieVšetko v kódeLen čo vidí v UI
ValidáciaRozumie validátoromTestuje reálne správanie
Ideálne preCI/CD, developmentQA, acceptance testing

Najlepší prístup: Použite oba!

bash
# 1. Scout pre development (rýchle, z kódu)
scout generate ./frontend

# 2. Sentinel pre QA (presné, z UI)
sentinel analyze https://staging.app.com

Kompletný QA Toolchain

Marker + Scout + Sentinel tvoria kompletný stack:

┌─────────────────────────────────────────────────────┐
│                     MARKER                           │
│   Pridá data-testid do komponentov                  │
│   (Automatické označenie elementov)                 │
└──────────────────────┬──────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────┐
│                     SCOUT                            │
│   Analyzuje kód → Generuje scenáre                  │
│   (Statická analýza + LLM)                          │
└──────────────────────┬──────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────┐
│                    SENTINEL                          │
│   Prehľadá bežiacu app → Validuje scenáre           │
│   (Dynamická analýza + LLM)                         │
└──────────────────────┬──────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────┐
│              PLAYWRIGHT / PYTEST                     │
│   Spustí automatizované testy                       │
└─────────────────────────────────────────────────────┘

Praktický workflow:

bash
# 1. Marker: Pridaj data-testid
python marker/main.py add --project ./frontend

# 2. Scout: Vygeneruj testy z kódu
python scout/main.py generate ./frontend --output ./tests

# 3. (Voliteľne) Sentinel: Validuj na staging
python sentinel/main.py --url https://staging.app.com

# 4. Spusti testy
pytest ./tests --base-url https://staging.app.com

Praktický príklad: Contact Form

Vstup (Angular komponent)

html
<!-- contact.component.html -->
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <div class="form-group">
    <label for="name">Name</label>
    <input 
      id="name"
      formControlName="name"
      data-testid="input-contact-name"
      required>
  </div>
  
  <div class="form-group">
    <label for="email">Email</label>
    <input 
      id="email"
      type="email"
      formControlName="email"
      data-testid="input-contact-email"
      required>
  </div>
  
  <div class="form-group">
    <label for="message">Message</label>
    <textarea
      id="message"
      formControlName="message"
      data-testid="textarea-contact-message"
      minlength="10">
    </textarea>
  </div>
  
  <button type="submit" data-testid="btn-contact-submit">
    Send Message
  </button>
</form>

Výstup (Playwright testy)

python
# test_contact.py - vygenerované Scoutom

def test_successful_contact_form_submission(page: Page, base_url: str):
    """Test successful form submission with valid data"""
    page.goto(f"{base_url}/contact")
    
    page.locator("[data-testid=\"input-contact-name\"]").fill("John Doe")
    page.locator("[data-testid=\"input-contact-email\"]").fill("john@example.com")
    page.locator("[data-testid=\"textarea-contact-message\"]").fill("Hello, this is a test message.")
    page.locator("[data-testid=\"btn-contact-submit\"]").click()


def test_contact_form_required_name(page: Page, base_url: str):
    """Test that name field is required"""
    page.goto(f"{base_url}/contact")
    
    # Leave name empty, fill other fields
    page.locator("[data-testid=\"input-contact-email\"]").fill("john@example.com")
    page.locator("[data-testid=\"textarea-contact-message\"]").fill("Test message here.")
    page.locator("[data-testid=\"btn-contact-submit\"]").click()
    
    # Verify form was not submitted
    expect(page.locator("[data-testid=\"input-contact-name\"]")).to_have_attribute("aria-invalid", "true")


def test_contact_form_email_validation(page: Page, base_url: str):
    """Test that email format is validated"""
    page.goto(f"{base_url}/contact")
    
    page.locator("[data-testid=\"input-contact-name\"]").fill("John")
    page.locator("[data-testid=\"input-contact-email\"]").fill("invalid-email")
    page.locator("[data-testid=\"btn-contact-submit\"]").click()
    
    # Verify email validation error


def test_contact_form_message_minlength(page: Page, base_url: str):
    """Test that message has minimum length requirement"""
    page.goto(f"{base_url}/contact")
    
    page.locator("[data-testid=\"input-contact-name\"]").fill("John")
    page.locator("[data-testid=\"input-contact-email\"]").fill("john@example.com")
    page.locator("[data-testid=\"textarea-contact-message\"]").fill("Short")  # < 10 chars
    page.locator("[data-testid=\"btn-contact-submit\"]").click()
    
    # Verify minlength validation

4 testy z jedného formulára - bez manuálnej práce!

Quick Start

bash
# 1. Nainštalujte Ollama a model
ollama pull qwen3-coder:30b

# 2. Nakonfigurujte .env
cat > .env << EOF
PROJECT_PATH=/path/to/frontend
OLLAMA_HOST=http://localhost:11434
LLM_MODEL=qwen3-coder:30b
OUTPUT_DIR=./result
EOF

# 3. Analyzujte projekt
python main.py analyze /path/to/frontend

# 4. Vygenerujte testy
python main.py generate /path/to/frontend

# 5. Spustite testy
pytest result/tests/ --base-url http://localhost:4200

Záver

Scout mení spôsob, ako vytvárame testy:

Manuálny prístupSo Scout
Čítam kód, píšem testyScout číta kód za mňa
Zabudnem na edge casesLLM generuje validation testy
Nekonzistentné pokrytieSystematická analýza všetkých komponentov
Hodiny práceMinúty

Kedy použiť Scout:

  • ✅ Potrebujete testy z existujúceho kódu
  • ✅ CI/CD pipeline bez staging servera
  • ✅ Rýchle generovanie počas developmentu
  • ✅ Analýza test coverage pred deployom

Scout je váš AI QA engineer - číta kód, rozumie mu a píše testy. Vy len kontrolujete výsledok.


Scout je súčasť QA automation toolchain spolu s Marker a Sentinel. Všetky nástroje používajú lokálne LLM modely cez Ollama.

Všetky články