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 testyVý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 testyVý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áreVýstup:
- JSON scenáre (Sentinel-kompatibilné)
- Python testy (Playwright + Pytest)
Príklad workflow
# 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 scenariosAko Scout analyzuje kód?
Scout používa regex patterns na detekciu elementov v rôznych frameworkoch:
Angular detekcia
<!-- 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
// 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
<!-- 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:
# 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: /dashboardToto umožňuje generovať testy s správnymi page.goto() volaniami.
Čo Scout vygeneruje?
1. Sentinel JSON formát
{
"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
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)
def test_successful_login():
# Vyplň správne údaje → očakávaj úspech2. Validation Tests (validácia)
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 error3. Navigation Tests (navigácia)
def test_navigation_to_about_page():
# Klikni na link → over že si na správnej stránke4. Edge Cases (hraničné prípady)
def test_form_with_special_characters():
# Vyplň špeciálne znaky → over správanieScout rozumie validácii
Scout detekuje validačné pravidlá vo vašom kóde:
// 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
<!-- 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:
# Spustite Marker gRPC server
cd ../marker && python grpc_server.py
# Scout pridá testid + vygeneruje scenáre
python main.py full /path/to/frontendWorkflow:
1. Scout analyzuje komponenty
2. Scout zavolá Marker → pridá data-testid
3. Scout znovu analyzuje (teraz s testid)
4. Scout vygeneruje scenáre3 spôsoby použitia
1. CLI (Command Line)
# 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 administrator2. gRPC Server
# Spustite server
python main.py grpc-server --port 50052
# Volajte z akéhokoľvek jazyka
# Service: ScoutService
# Methods: Analyze, Generate, FullWorkflow3. MCP Server (Claude integrácia)
// 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_generateScout vs Sentinel: Kedy čo použiť?
| Aspekt | Scout | Sentinel |
|---|---|---|
| Prístup | Statická analýza kódu | Dynamická analýza UI |
| Potrebuje | Zdrojový kód | Bežiacu aplikáciu |
| Rýchlosť | Rýchlejšie | Pomalšie (naviguje UI) |
| Pokrytie | Všetko v kóde | Len čo vidí v UI |
| Validácia | Rozumie validátorom | Testuje reálne správanie |
| Ideálne pre | CI/CD, development | QA, acceptance testing |
Najlepší prístup: Použite oba!
# 1. Scout pre development (rýchle, z kódu)
scout generate ./frontend
# 2. Sentinel pre QA (presné, z UI)
sentinel analyze https://staging.app.comKompletný 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:
# 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.comPraktický príklad: Contact Form
Vstup (Angular komponent)
<!-- 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)
# 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 validation4 testy z jedného formulára - bez manuálnej práce!
Quick Start
# 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:4200Záver
Scout mení spôsob, ako vytvárame testy:
| Manuálny prístup | So Scout |
|---|---|
| Čítam kód, píšem testy | Scout číta kód za mňa |
| Zabudnem na edge cases | LLM generuje validation testy |
| Nekonzistentné pokrytie | Systematická analýza všetkých komponentov |
| Hodiny práce | Minú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.