infoclaw.ru
  • Что такое OpenClaw
  • Установка
  • Навыки
  • Интеграции
  • Сравнения
  • Новости
FAQ
  1. Главная
  2. Для разработчиков
  3. Unit-тестирование с OpenClaw: агент пишет тесты за вас
Для разработчиков

Unit-тестирование с OpenClaw: агент пишет тесты за вас

Как использовать OpenClaw для написания unit-тестов: Vitest, Jest, pytest. Промпты, паттерны, интеграция в CI/CD и автогенерация тестов при коммите.

24 марта 2026 г. · 6 мин чтения
Unit-тестирование с OpenClaw: агент пишет тесты за вас

Написание тестов — одна из задач, где OpenClaw экономит больше всего времени. Агент читает реализацию, понимает логику и генерирует полное тестовое покрытие за минуты. Этот гайд — о том, как встроить это в ежедневный workflow.

Базовый промпт для генерации тестов

Самый простой способ — открыть OpenClaw в папке проекта и попросить:

> Напиши unit-тесты для функции validateEmail в src/utils/validation.ts.
  Используй Vitest. Покрой: валидные email'ы, невалидные, граничные случаи (пустая строка, null, очень длинный).
  Файл тестов: src/utils/validation.test.ts

OpenClaw прочитает файл, поймёт сигнатуру функции и напишет тесты.

Пример: тесты для TypeScript-функции

Исходный код src/utils/pricing.ts:

export function calculateDiscount(
  price: number,
  discountPercent: number,
  userTier: "basic" | "premium" | "enterprise"
): number {
  if (price < 0) throw new Error("Price cannot be negative");
  if (discountPercent < 0 || discountPercent > 100) {
    throw new Error("Discount must be between 0 and 100");
  }

  const tierMultiplier = { basic: 1, premium: 1.1, enterprise: 1.25 };
  const effectiveDiscount = discountPercent * tierMultiplier[userTier];

  return price * (1 - Math.min(effectiveDiscount, 100) / 100);
}

Промпт OpenClaw:

> Напиши исчерпывающие Vitest-тесты для calculateDiscount.
  Файл: src/utils/pricing.test.ts
  Покрой все ветки: разные tier'ы, граничные значения, исключения.
  Используй describe/it, добавь комментарии для каждой группы тестов.

Сгенерированные тесты:

import { describe, it, expect } from "vitest";
import { calculateDiscount } from "./pricing";

describe("calculateDiscount", () => {
  describe("basic tier", () => {
    it("applies discount correctly", () => {
      expect(calculateDiscount(100, 10, "basic")).toBe(90);
    });

    it("returns full price when discount is 0", () => {
      expect(calculateDiscount(100, 0, "basic")).toBe(100);
    });

    it("returns 0 for 100% discount", () => {
      expect(calculateDiscount(100, 100, "basic")).toBe(0);
    });
  });

  describe("premium tier", () => {
    it("applies 10% tier multiplier to discount", () => {
      // 20% скидка × 1.1 = 22%, цена = 78
      expect(calculateDiscount(100, 20, "premium")).toBeCloseTo(78, 5);
    });

    it("caps effective discount at 100%", () => {
      // 100% × 1.1 = 110% → ограничивается до 100%
      expect(calculateDiscount(100, 100, "premium")).toBe(0);
    });
  });

  describe("enterprise tier", () => {
    it("applies 25% tier multiplier to discount", () => {
      // 20% скидка × 1.25 = 25%, цена = 75
      expect(calculateDiscount(100, 20, "enterprise")).toBe(75);
    });
  });

  describe("validation errors", () => {
    it("throws for negative price", () => {
      expect(() => calculateDiscount(-1, 10, "basic")).toThrow("Price cannot be negative");
    });

    it("throws for discount below 0", () => {
      expect(() => calculateDiscount(100, -1, "basic")).toThrow("Discount must be between 0 and 100");
    });

    it("throws for discount above 100", () => {
      expect(() => calculateDiscount(100, 101, "basic")).toThrow("Discount must be between 0 and 100");
    });
  });

  describe("edge cases", () => {
    it("handles zero price", () => {
      expect(calculateDiscount(0, 50, "basic")).toBe(0);
    });

    it("handles fractional prices", () => {
      expect(calculateDiscount(9.99, 10, "basic")).toBeCloseTo(8.991, 3);
    });
  });
});

Тесты для Python с pytest

> Напиши pytest-тесты для класса UserRepository в app/repositories/user.py.
  Используй pytest-mock для мокирования базы данных.
  Покрой: create, get_by_id, update, delete, not found кейс.
# tests/test_user_repository.py
import pytest
from unittest.mock import MagicMock, patch
from app.repositories.user import UserRepository
from app.models.user import User

@pytest.fixture
def mock_db():
    return MagicMock()

@pytest.fixture
def repo(mock_db):
    return UserRepository(mock_db)

class TestUserRepository:
    def test_create_user(self, repo, mock_db):
        user_data = {"name": "Alice", "email": "alice@example.com"}
        mock_db.execute.return_value.lastrowid = 42

        result = repo.create(user_data)

        mock_db.execute.assert_called_once()
        assert result.id == 42

    def test_get_by_id_found(self, repo, mock_db):
        mock_db.execute.return_value.fetchone.return_value = {
            "id": 1, "name": "Bob", "email": "bob@example.com"
        }

        user = repo.get_by_id(1)

        assert user is not None
        assert user.name == "Bob"

    def test_get_by_id_not_found(self, repo, mock_db):
        mock_db.execute.return_value.fetchone.return_value = None

        user = repo.get_by_id(999)

        assert user is None

    def test_update_user(self, repo, mock_db):
        mock_db.execute.return_value.rowcount = 1

        result = repo.update(1, {"name": "Bob Updated"})

        assert result is True

    def test_delete_user(self, repo, mock_db):
        mock_db.execute.return_value.rowcount = 1

        result = repo.delete(1)

        assert result is True

Автогенерация тестов при коммите (Git Hook)

Настройте pre-commit хук, который генерирует тесты для изменённых файлов:

# .git/hooks/pre-commit
#!/bin/bash

# Находим изменённые .ts файлы без тестов
CHANGED=$(git diff --cached --name-only | grep '\.ts$' | grep -v '\.test\.')

for file in $CHANGED; do
  test_file="${file%.ts}.test.ts"

  if [ ! -f "$test_file" ]; then
    echo "⚠️  No tests for: $file"
    echo "Generating tests with OpenClaw..."

    openclaw --no-interactive << EOF
Напиши Vitest unit-тесты для $file.
Создай файл $test_file.
Используй describe/it, покрой основные кейсы и граничные значения.
EOF

    git add "$test_file"
    echo "✓ Tests generated: $test_file"
  fi
done
chmod +x .git/hooks/pre-commit

Интеграция в CI/CD с GitHub Actions

# .github/workflows/test-coverage.yml
name: Test Coverage

on: [pull_request]

jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '22'

      - run: npm ci

      - name: Run tests with coverage
        run: npm run test -- --coverage

      - name: Check coverage threshold
        run: |
          COVERAGE=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
          echo "Coverage: $COVERAGE%"
          if (( $(echo "$COVERAGE < 80" | bc -l) )); then
            echo "❌ Coverage below 80%"
            exit 1
          fi

      - name: Comment coverage on PR
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json'));
            const pct = summary.total.lines.pct;
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Test Coverage: ${pct}% lines\n${pct >= 80 ? '✅' : '❌'} Threshold: 80%`
            });

Продвинутый промпт: TDD-режим

Если хотите писать тесты до реализации:

> Напиши тесты для функции formatPhoneNumber которую я сейчас буду реализовывать.
  Требования:
  - Принимает строку с номером телефона в любом формате
  - Возвращает формат: +7 (999) 123-45-67
  - Бросает ошибку если номер невалиден
  - Поддерживает: +7, 8, 7 в начале

  Файл: src/utils/phone.test.ts
  Реализации ещё нет — пиши только тесты.

OpenClaw напишет тесты-спецификации. Вы реализуете функцию под них.

Тестирование React-компонентов

> Напиши тесты для компонента LoginForm в src/components/LoginForm.tsx.
  Используй Vitest + React Testing Library.
  Покрой: рендеринг формы, валидацию полей, успешный сабмит, отображение ошибки от API.
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { LoginForm } from "./LoginForm";

describe("LoginForm", () => {
  it("renders email and password fields", () => {
    render(<LoginForm onSubmit={vi.fn()} />);

    expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
  });

  it("shows validation error for invalid email", async () => {
    render(<LoginForm onSubmit={vi.fn()} />);

    await userEvent.type(screen.getByLabelText(/email/i), "not-an-email");
    await userEvent.click(screen.getByRole("button", { name: /войти/i }));

    expect(screen.getByText(/неверный формат email/i)).toBeInTheDocument();
  });

  it("calls onSubmit with credentials on valid form", async () => {
    const onSubmit = vi.fn().mockResolvedValue({ success: true });
    render(<LoginForm onSubmit={onSubmit} />);

    await userEvent.type(screen.getByLabelText(/email/i), "user@example.com");
    await userEvent.type(screen.getByLabelText(/password/i), "password123");
    await userEvent.click(screen.getByRole("button", { name: /войти/i }));

    await waitFor(() => {
      expect(onSubmit).toHaveBeenCalledWith({
        email: "user@example.com",
        password: "password123",
      });
    });
  });
});

Советы по качеству

Проверяйте тесты перед коммитом: npm run test — и только потом в Git.

Просите конкретику: «покрой граничные значения и исключения» лучше чем «напиши тесты».

Итерируйте: если тест не проходит, покажите агенту ошибку — он исправит.

Не копируйте слепо: просматривайте сгенерированные тесты. Иногда агент предполагает поведение, которое нужно уточнить.

Итог

OpenClaw генерирует тесты быстрее, чем их пишет человек — но важно понимать что они покрывают. Используйте агента для рутинного покрытия, сами пишите тесты для критической бизнес-логики. Такая комбинация даёт и скорость, и надёжность.

Читайте также: VS Code workflow разработчика и GitHub интеграция.

Теги: тестированиеunit testsVitestJestpytestCI/CDTDDавтоматизация

Вам также может быть интересно

Для разработчиков

OpenClaw API для разработчиков: интеграция в свои проекты

18 марта 2026 г. 6 мин
Для разработчиков

OpenClaw + VS Code (VSCode / Visual Studio Code): workflow разработчика в 2026

24 марта 2026 г. 9 мин
Интеграции

OpenClaw + GitHub: автоматизация разработки с AI-агентом

23 марта 2026 г. 6 мин
💰
Инструмент Калькулятор стоимости AI-моделей Сравните цены GPT-4o, Claude, DeepSeek за минуту
→
🎯
Квиз · 2 мин Какой OpenClaw подходит вам? 5 вопросов — персональная рекомендация
→

Популярное

  1. Moltbook: соцсеть для AI-агентов с 1,5 миллиона ботов Что такое OpenClaw
  2. OpenClaw купил автомобиль: как AI-агент сэкономил $4,200 Сценарии использования
  3. Multi-agent в OpenClaw: как запустить команду AI-агентов Сценарии использования
  4. Что такое OpenClaw: полный гид по первому вирусному ИИ-агенту 2026 года Что такое OpenClaw
  5. OpenClaw сделал @openclaw/gateway-protocol доступным для публикации в npm Новости

Категории

  • Что такое OpenClaw (8)
  • Установка (16)
  • Навыки (11)
  • Интеграции (15)
  • Сравнения (9)
  • Сценарии использования (22)
  • Новости (97)
  • Enterprise / NemoClaw (7)
  • Безопасность (10)
  • Сообщество (1)
  • Для разработчиков (6)
  • Вопросы и ответы (2)
  • Глоссарий (4)

Недавнее

  • OpenClaw сделал @openclaw/gateway-protocol доступным для публикации в npm сегодня
  • OpenClaw 2026.7.2-beta.3: новые возможности удалённых сессий, автоматизации и безопасности вчера
  • OpenClaw 2026.7.2-beta.2: расширенные удалённые сессии и улучшения безопасности 2 дн. назад

Быстрый старт

Новичок в OpenClaw? Начните отсюда:

  • → Что такое OpenClaw
  • → Установка за 10 минут
  • → Топ-10 навыков
  • → Подключить Telegram

Теги

установканавыкиtelegramwhatsappmacoswindowsenterpriseголосopen-sourcellmprivacynode.js
infoclaw.ru

Независимый информационный ресурс об ИИ-агенте OpenClaw. Статьи, гайды и новости на русском языке.

Разделы

  • Что такое OpenClaw
  • Установка
  • Навыки
  • Интеграции
  • Сравнения
  • Enterprise
  • Безопасность
  • Новости

Интеграции

  • Telegram
  • WhatsApp
  • Slack
  • Discord
  • iMessage
  • Teams
  • Matrix
  • Все (20+) →

Ресурсы

  • Вопросы и ответы
  • Глоссарий
  • Для разработчиков
  • Сообщество
  • Карта сайта

© 2026 infoclaw.ru — Независимый ресурс. Не является официальным сайтом проекта OpenClaw.

Политика конфиденциальности Пользовательское соглашение Контакты