mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-15 02:14:57 +03:00
feat(web-test): test-раннер пишет человеческий отчёт в stdout, JSON по --report=-
Команда `test` приведена к поведению тест-раннеров (jest/pytest/playwright): человеческий отчёт со сводкой в последней строке идёт в stdout, а машинный JSON/JUnit — опционально через `--report=-` (Unix-конвенция `-` = stdout), при этом прогресс уезжает в stderr. Убран безусловный дамп JSON в stdout, из-за которого `test … | tail` хоронил сводку под отчётом. - test.mjs: writer выбирается по режиму (--report=- → stderr-прогресс); развилка `-` в обеих ветках записи (json и junit), чтобы не плодить файл "-"; валидация: --report=- несовместимо с --format=allure (каталог, не поток). - util.mjs: строка --report=- в справке. - Документация (spec/guide/regress/README) приведена к фактическому английскому выводу и описывает матрицу потоков stdout/stderr. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -366,10 +366,11 @@ node $RUN test tests/<app-name>/ --tags=smoke # by tag
|
||||
node $RUN test tests/<app-name>/ --grep='накладн' # by name regex
|
||||
node $RUN test tests/<app-name>/ --bail --retry=1 # stop on first fail, allow 1 retry
|
||||
node $RUN test tests/<app-name>/ --report=allure-results --format=allure --report-dir=allure-results
|
||||
node $RUN test tests/<app-name>/ --report=- # machine JSON to stdout, progress to stderr
|
||||
node $RUN test tests/<app-name>/ -- --rebuild-stand # after `--` → hookArgs
|
||||
```
|
||||
|
||||
Default report is JSON when `--report=…` is given. Allure needs `--format=allure` + a directory. JUnit similarly with `--format=junit`.
|
||||
**Output contract.** `test` behaves like a test runner: by default the human report (with the summary as the last line) goes to **stdout** — read the tail of stdout + exit code. The machine report is opt-in via `--report`: `--report=path` writes it to a file (default JSON; XML for `--format=junit`), `--report=-` writes it to stdout while progress moves to stderr. Allure needs `--format=allure` + a directory (`-` is invalid for allure). For detailed triage use `--report=path` or `--report=-`. **In `--report=-` mode never use `2>&1`** — it merges stderr progress into the stdout JSON. (In the default mode there is no JSON in stdout, so `… | tail` is safe.)
|
||||
|
||||
### Allure static config — `_allure/`
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// web-test cli/commands/test v1.0 — regression test runner
|
||||
// web-test cli/commands/test v1.1 — regression test runner
|
||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import { existsSync, writeFileSync, mkdirSync } from 'fs';
|
||||
import { resolve, dirname, basename, relative } from 'path';
|
||||
@@ -96,9 +96,15 @@ export async function cmdTest(rawArgs) {
|
||||
if (opts.format === 'junit' && !opts.report) {
|
||||
die('--format=junit requires --report=path.xml');
|
||||
}
|
||||
// `--report=-` means "machine report to stdout" (Unix `-` convention).
|
||||
// Only meaningful for streamable formats (json/junit); allure is a directory.
|
||||
const reportToStdout = opts.report === '-';
|
||||
if (reportToStdout && opts.format === 'allure') {
|
||||
die('--report=- (stdout) is not valid with --format=allure: allure emits a directory of files, not a single stream. Use --report-dir=<dir> instead.');
|
||||
}
|
||||
const reportDir = opts.reportDir
|
||||
? resolve(opts.reportDir)
|
||||
: (opts.report ? dirname(resolve(opts.report)) : testDir);
|
||||
: (opts.report && !reportToStdout ? dirname(resolve(opts.report)) : testDir);
|
||||
if (opts.screenshot !== 'off') {
|
||||
try { mkdirSync(reportDir, { recursive: true }); } catch {}
|
||||
}
|
||||
@@ -154,8 +160,9 @@ export async function cmdTest(rawArgs) {
|
||||
hooks = await import('file:///' + hooksPath.replace(/\\/g, '/'));
|
||||
}
|
||||
|
||||
// Console header
|
||||
const W = process.stderr;
|
||||
// Human-readable report goes to stdout (test-runner convention: jest/pytest/playwright).
|
||||
// In `--report -` mode the machine JSON/XML takes over stdout, so progress moves to stderr.
|
||||
const W = reportToStdout ? process.stderr : process.stdout;
|
||||
W.write(`\nweb-test -- ${url}\n`);
|
||||
W.write(`Running ${filtered.length} tests from ${relative(process.cwd(), testDir).replace(/\\/g, '/') || '.'}/\n\n`);
|
||||
|
||||
@@ -418,13 +425,14 @@ export async function cmdTest(rawArgs) {
|
||||
summary: { total: results.length, passed: passCount, failed: failCount, skipped: skipCount },
|
||||
tests: results,
|
||||
};
|
||||
out(report);
|
||||
|
||||
if (opts.format === 'allure') {
|
||||
writeAllure(results, reportDir, severityIndex);
|
||||
syncAllureExtras(testDir, reportDir);
|
||||
} else if (opts.format === 'junit') {
|
||||
writeFileSync(resolve(opts.report), buildJUnit(report, testDir));
|
||||
if (reportToStdout) process.stdout.write(buildJUnit(report, testDir) + '\n');
|
||||
else writeFileSync(resolve(opts.report), buildJUnit(report, testDir));
|
||||
} else if (reportToStdout) {
|
||||
out(report);
|
||||
} else if (opts.report) {
|
||||
writeFileSync(resolve(opts.report), JSON.stringify(report, null, 2));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// web-test cli/util v1.0 — generic helpers for CLI commands
|
||||
// web-test cli/util v1.1 — generic helpers for CLI commands
|
||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
export function out(obj) {
|
||||
@@ -100,7 +100,8 @@ Options for test:
|
||||
--bail Stop on first failure
|
||||
--retry=N Retry failed tests N times
|
||||
--timeout=ms Per-test timeout (default: 30000)
|
||||
--report=path Write JSON report to file
|
||||
--report=path Write machine report (JSON/JUnit) to file
|
||||
--report=- Write machine report to stdout (progress moves to stderr)
|
||||
--report-dir=path Directory for screenshots and other artifacts
|
||||
--screenshot=mode on-failure (default) | every-step | off
|
||||
--format=fmt json (default) | allure | junit
|
||||
|
||||
@@ -241,9 +241,9 @@ export default async function({
|
||||
✗ Проведение приходной накладной (12.7s)
|
||||
└ Заполнить табличную часть (5.2s)
|
||||
Не найден столбец "Цена" в табличной части "Товары"
|
||||
скриншот: tests/учёт-поступлений/error-shot.png
|
||||
screenshot: tests/учёт-поступлений/error-shot.png
|
||||
|
||||
23 пройдено, 1 упал, 0 пропущено (3 мин 42 с)
|
||||
23 passed, 1 failed, 0 skipped (3m 42s)
|
||||
```
|
||||
|
||||
### Подробный отчёт
|
||||
|
||||
@@ -22,7 +22,8 @@ node run.mjs test [url] <dir|file> [флаги]
|
||||
| `--bail` | false | Остановиться при первом падении |
|
||||
| `--retry=N` | 0 | Повторить упавшие тесты N раз |
|
||||
| `--timeout=ms` | 30000 | Таймаут на тест (мс) |
|
||||
| `--report=path` | (нет) | Записать отчёт в файл (JSON или XML для `--format=junit`) |
|
||||
| `--report=path` | (нет) | Записать машинный отчёт в файл (JSON или XML для `--format=junit`) |
|
||||
| `--report=-` | (нет) | Машинный отчёт в stdout (`-` = stdout); человеческий прогресс уходит в stderr |
|
||||
| `--format=fmt` | json | Формат отчёта: `json` / `allure` / `junit` |
|
||||
| `--report-dir=path` | dirname(report) / testDir | Каталог для скриншотов, видео, Allure-результатов |
|
||||
| `--screenshot=strategy` | on-failure | `on-failure` / `every-step` / `off` |
|
||||
@@ -35,7 +36,20 @@ URL необязателен, если в каталоге тестов есть
|
||||
|
||||
- `--screenshot=<v>` принимается только `on-failure | every-step | off`; при невалидном значении движок выводит ошибку и завершается с ненулевым кодом до старта прогона.
|
||||
- `--format=<v>` принимается только `json | allure | junit`; иначе — завершение с ошибкой.
|
||||
- `--format=junit` требует `--report=<path>` (иначе некуда писать XML); иначе — завершение с ошибкой.
|
||||
- `--format=junit` требует `--report=<path>` (иначе некуда писать XML); иначе — завершение с ошибкой. Значение `-` (stdout) для junit допустимо.
|
||||
- `--report=-` (stdout) несовместимо с `--format=allure`: allure пишет каталог, а не поток; иначе — завершение с ошибкой.
|
||||
|
||||
### Потоки вывода (stdout / stderr)
|
||||
|
||||
`test` ведёт себя как тест-раннер (jest/pytest/playwright): человеческий отчёт со сводкой в конце идёт в **stdout**. Машинный отчёт (JSON/JUnit) включается отдельно флагом `--report`.
|
||||
|
||||
| Запуск | stdout | stderr | Файл |
|
||||
|--------|--------|--------|------|
|
||||
| `test …` (дефолт) | человеческий отчёт, **сводка последней строкой** | — | — |
|
||||
| `test … --report=file` | человеческий отчёт (виден прогресс + сводка) | — | JSON/JUnit в файл |
|
||||
| `test … --report=-` | **чистый машинный отчёт** (JSON или JUnit-XML) | человеческий прогресс | — |
|
||||
| `--format=allure …` | человеческий отчёт | — | артефакты allure в каталоге |
|
||||
| любой | — | — | exit code **0/1** всегда |
|
||||
|
||||
### Режим выполнения
|
||||
|
||||
@@ -753,9 +767,11 @@ await step('Кладовщик проверяет статус', async () => {
|
||||
|
||||
## 10. Консольный вывод
|
||||
|
||||
Вывод — на английском (статусы `passed/failed/skipped` зеркалят ключи JSON-отчёта и Allure/JUnit):
|
||||
|
||||
```
|
||||
web-test — http://localhost/app/ru_RU
|
||||
Запуск 25 тестов из tests/myapp/
|
||||
web-test -- http://localhost/app/ru_RU
|
||||
Running 25 tests from tests/myapp/
|
||||
|
||||
✓ Навигация по разделам (2.1s)
|
||||
✓ CRUD справочника Контрагенты (12.3s)
|
||||
@@ -766,13 +782,15 @@ web-test — http://localhost/app/ru_RU
|
||||
├ Открыть форму (2.0s)
|
||||
└ ✗ Сохранить пустую форму (6.1s)
|
||||
Ожидалось модальное окно ошибки, но форма сохранилась
|
||||
скриншот: error-shot-10.png
|
||||
screenshot: error-shot-10.png
|
||||
○ Составной тип (skip: не реализовано)
|
||||
|
||||
23 passed, 1 failed, 1 skipped (2m 0.5s)
|
||||
```
|
||||
|
||||
Для passed-тестов выводится одна строка `✓ name (duration)`. Шаги печатаются только для упавших — после строки `✗`, с отступом, плюс сообщение ошибки и путь к скриншоту. Полная картина по шагам — в JSON-отчёте (`--report=…`).
|
||||
Для passed-тестов выводится одна строка `✓ name (duration)`. Шаги печатаются только для упавших — после строки `✗`, с отступом, плюс сообщение ошибки и путь к скриншоту (`screenshot:`). Полная картина по шагам — в машинном отчёте (`--report=…` или `--report=-`).
|
||||
|
||||
По умолчанию этот отчёт идёт в **stdout** и заканчивается строкой сводки (`N passed, M failed, K skipped (Xs)`) — модель читает хвост stdout + exit code. В режиме `--report=-` (Unix-конвенция `-` = stdout) stdout занимает чистый машинный отчёт (JSON/JUnit), а человеческий прогресс уходит в stderr.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@ Exit code: 0 = все прошли, 1 = есть падения.
|
||||
| `--bail` | Остановиться на первой ошибке |
|
||||
| `--retry=N` | Перепрогон упавших тестов N раз |
|
||||
| `--timeout=ms` | Таймаут одного теста (default 30000) |
|
||||
| `--report=path` | Сохранить отчёт в файл |
|
||||
| `--report=path` | Сохранить машинный отчёт в файл |
|
||||
| `--report=-` | Машинный отчёт в stdout (прогресс → stderr) |
|
||||
| `--format=json\|allure\|junit` | Формат отчёта |
|
||||
| `--report-dir=path` | Корень для Allure/JUnit артефактов |
|
||||
| `--screenshot=on-failure\|every-step\|off` | Когда снимать скриншоты |
|
||||
|
||||
Reference in New Issue
Block a user