176 lines
30 KiB
Markdown
176 lines
30 KiB
Markdown
# QA Analysis
|
||
|
||
Ревизия спеков: G2 approved (comment 3082). Источник ожидаемого поведения — только
|
||
Delta Specs `portfolio-concentration` (28 ADDED, ниже PC) и `portfolio-view`
|
||
(2 MODIFIED + 2 ADDED, ниже PVΔ) этого change. Design пишется параллельно; на его
|
||
внутреннее устройство не опираемся. Case пишется только там, где нужны данные, шаги или oracle сверх Scenario;
|
||
остальные строки Coverage Matrix ссылаются на Scenarios. Написанные cases — в
|
||
`analysis/test-cases/{conc,meta,reg}.md`.
|
||
|
||
## Risk Assessment
|
||
|
||
| Риск | Затронутые требования | Вероятность | Ущерб | Глубина проверки |
|
||
| --- | --- | --- | --- | --- |
|
||
| Неверная классификация исхода получения (NOT_FOUND vs иная ошибка) ломает 24h-отсчёт и last-known | «Результат получения сектора и эмитента», F02–F05 | Высокая (клиент AS-IS отображает NOT_FOUND как Unavailable — failure-model:75) | Средний: группы «не указан» вместо значений | Интеграционные проверки всех 4 строк таблицы исходов + exploratory Q-F3 |
|
||
| Доли/суммы считаются от неверной базы (Cash Balance, нули, другие валюты, отрицательные) | PC:129, PC:144, PC:289 | Средняя | Высокий: недоверие владельца к цифрам | Компонентные проверки с числовыми оракулами из сценариев |
|
||
| Потеря/порча финансового Snapshot из-за обогащения (token, публикация, границы подключения) | «Свежесть и fallback полного Portfolio Snapshot», F08–F11 | Низкая | Критический: потеря данных портфеля | Интеграционные: token-отказ, гонка публикации, смена подключения; регрессия обхода |
|
||
| Ошибка округления/формата долей (`,0`, `< 0,1 %`, половина вверх) | PC:304, PC:324 | Средняя | Низкий | Компонентные с точными строками-эталонами |
|
||
| Ухудшение существующей вкладки «Позиций» / структуры портфеля | PC:9, регрессия | Средняя | Высокий | Регрессионный прогон (TC-REG) |
|
||
| Доступность диаграммы только цветом / недоступна скринридеру | PC:443 | Средняя | Средний | Ручная проверка + текстовый эквивалент в component |
|
||
| Квоты T-Bank при суточном обходе (до `U + A` вызовов) | F07, Q-F3 | Неизвестная | Средний: деградация синхронизации | Exploratory Q-F3 на тестовом токене; norm от квот не зависит |
|
||
|
||
## Coverage Matrix
|
||
|
||
Уровни: unit / integration (backend, configured HTTP tests) / component (frontend) / e2e / manual.
|
||
Ссылки на сценарии — `PC:<строка>` / `PVΔ:<строка>` файлов спек.
|
||
|
||
| Requirement | Сценарии / ветви | Проверка / ожидаемое наблюдение | Уровень | Test cases |
|
||
| --- | --- | --- | --- | --- |
|
||
| PC:9 Вкладка «Концентрация» страницы счёта | 2 сценария (есть вкладка; «Все счета» — нет) + инвариант «прочие вкладки не меняются» | Вкладка рядом с «Позициями»; в «Всех счетах» отсутствует; дефолтная вкладка прежняя | e2e | Scenario «Вкладка на странице одного счёта», «Режим “Все счета”»; TC-REG-001 |
|
||
| PC:20 Вкладка в состояниях страницы | загрузка/ошибка/пусто/только Cash Balance | Вкладки нет при загрузке, ошибке и пустом Portfolio; есть при любом Cash Balance | component + e2e | TC-CONC-002 + Scenario «Загрузка и ошибка» |
|
||
| PC:37 Переключение разрезов | 4 разреза, один одновременно, порядок | Показан ровно один разрез, переключатели в заданном порядке | component | Scenario «Открытие вкладки», «Переключение разреза» |
|
||
| PC:49 Начальное состояние вкладки | новый заход/reload → «Акции»+первая валюта; вкладки страницы → сохранение | Reset при новом заходе и смене счёта, persist при переключении вкладок | e2e | TC-CONC-005, TC-CONC-006 |
|
||
| PC:69 Состав разрезов | 3 сценария (сектор объединяет; эмитент stock+bond без фонда; фонд вне акций/облигаций) | Агрегация и исключение типов по таблице | component | TC-CONC-007 |
|
||
| PC:96 Названия элементов | без name → ticker; `issuer.name`; разные `issuer.id` не сливаются | Название по цепочке name→ticker→FIGI; раздельные элементы при равных именах | component | TC-CONC-008 |
|
||
| PC:114 Название эмитента при разных названиях бренда | наибольшее `currentValue`; равные → меньший по алфавиту | Элемент назван по большей позиции; при равенстве — «Сбер» < «Сбербанк» | component | Scenario «Название по наибольшей позиции», «Равные наибольшие значения» |
|
||
| PC:129 Позиции, учитываемые в разрезе | положительные; 0 — не учитывается и не неучтённая; null/отрицательные исключены | Сумма разреза только из положительных позиций выбранной валюты | component | Scenario «Отрицательная и неоценённая позиции», «Позиция с нулевой стоимостью» |
|
||
| PC:144 Сноска о не учтённых позициях | N: null в любой валюте + отрицательные в выбранной; 0 → нет сноски | Точный N по правилу; сценарии 149–167 покрывают все ветви | component | Scenario «Сноска с числом позиций», «Неоценённая позиция при смене валюты», «Отрицательная позиция другой валюты», «Нет неучтённых позиций» |
|
||
| PC:169 Одна валюта за раз | смена валюты пересчитывает; сохраняется между разрезами; нет конвертации | Значения только в выбранной валюте, без смешанного итога | component | Scenario «Смена валюты», «Валюта сохраняется при смене разреза» |
|
||
| PC:184 Доступные валюты вкладки | STOCK/BOND/FUND ненулевые, включая отрицательные; 0 исключён; Select скрыт при ≤1; сортировка ISO | Список и сортировка точны; скрытие Select; пустое состояние без выбора | component | Scenario «Начальная валюта», «Единственная валюта», «Валюта только у позиции с нулевой стоимостью», «Валюта только у отрицательной позиции», «Нет оценённых позиций» |
|
||
| PC:214 Независимый выбор валюты вкладки | независимость от «Структуры портфеля»; пропавшая валюта → первая списка | Валюта вкладки не меняется от внешнего Select; fallback при исчезновении | component + e2e | TC-CONC-015 |
|
||
| PC:229 Топ-5 и строка «Прочее» | ≤6 строк без «Прочее» (5, 6, <5); ≥7 → топ-5 + «Прочее» с числом элементов | Границы 5/6/7 и формулировка числа элементов («2 элемента», «5 элементов») | component | TC-CONC-016 |
|
||
| PC:254 Раскрытие строки «Прочее» | раскрытие/сворачивание (мышь и клавиатура); не меняет топ-5 и диаграмму; свёрнуто при показе/смене валюты | Список остальных в порядке ранжирования; инвариант неизменности топ-5 | component + e2e | Scenario «Раскрытие “Прочее”», «Повторное нажатие», «Смена валюты сворачивает “Прочее”»; клавиатура — TC-CONC-027 |
|
||
| PC:274 Порядок элементов с равной суммой | цифры < латиница < кириллица, без регистра; граница 5-й строки | Порядок «VK», «X5», «Сбер»; «Альфа» в топ-5 при равенстве | component | Scenario «Равные суммы на границе пятой строки», «Цифры, латиница и кириллица при равных суммах» |
|
||
| PC:289 Расчёт долей | точные доли суммируются в 100 %; доля «Прочее» = сумма долей элементов; Cash Balance вне | Числовые оракулы сценариев 294–302 | component | Scenario «Доля без денежных остатков», «Доля “Прочее”»; числовой прогон — TC-CONC-007 |
|
||
| PC:304 Показ долей | округление до десятых, половина вверх, без «,0», «< 0,1 %», сумма ≠ 100 % допустима | Строки-эталоны «93,8 %», «6,3 %», «< 0,1 %», 100,1 % в сумме | component | TC-CONC-020 (все три ветви: середина вверх, «< 0,1 %», без «,0», сумма ≠ 100 %) |
|
||
| PC:324 Суммарная доля топ-5 | показ при ≥6, скрыта при ≤5 (7/6/5/1 элементы) | «Топ-5 · N %» только при ≥6; значения 95 %, 96 % | component | Ветви покрыты TC-CONC-016 (наборы 1–4) |
|
||
| PC:349 Группы «Сектор/Эмитент не указан» | группа ранжируется наравне, попадает в «Прочее», имя видно | Сценарии 354–362 | component | Scenario «Позиции без эмитента в топе», «Группа без сектора в “Прочее”» |
|
||
| PC:364 Подписи секторов | известные — русская подпись, неизвестные — как получено; нет своей классификации | Неизвестный код показан буквально | component | Scenario «Неизвестное значение сектора» |
|
||
| PC:374 Русские подписи известных секторов | 11 значений таблицы, включая `government` | Каждое значение → своя подпись (таблица — эталон) | component | TC-CONC-024 |
|
||
| PC:402 Диаграмма распределения разреза | 6 сегментов при ≤6; 5+«Прочее» при ≥7; одинаково при раскрытии; нет при пустом разрезе | Число сегментов и доли совпадают со списком | component + manual | Scenario «Семь элементов», «Ровно шесть элементов» (обе диаграммные нормы); визуальный блок — TC-CONC-027 |
|
||
| PC:415 Центр диаграммы | сумма точная; «Топ-5 · N %» при метрике; текстовый эквивалент | Центр: «95 %» + «1 000 ₽» / только сумма при ≤5 | component + manual | Scenario «Семь элементов», «Ровно шесть элементов» (обе диаграммные нормы); визуальный блок — TC-CONC-027 |
|
||
| PC:430 Строки без переходов | клик по строке — нет навигации; эмитенты без логотипов | URL не меняется; нет `<img>` логотипов | e2e | Scenario «Нажатие на строку акции», «Строка эмитента» |
|
||
| PC:443 Доступность диаграммы без цвета | текстовый эквивалент, сопоставимость сегментов без цвета | Скринридер читает название/сумму/долю каждого сегмента | manual + component | TC-CONC-027 |
|
||
| PC:451 Пустое состояние разреза | пустой разрез: заголовок + валюта, без списка/диаграммы; сноска и выбор сохраняются | Сценарий «Валюта только у отрицательной позиции» | component | Scenario «Валюта только у отрицательной позиции» (пустое состояние) |
|
||
| PC:464 Предупреждение о неполных данных | неполнота `meta` → одно «Данные неполные» на вкладке, без дублирования на странице; неоценённые позиции не вызывают | Одно сообщение; доли по доступным данным | component + e2e | Scenario «Неполный Portfolio», «Предупреждение не дублируется» |
|
||
| PC:484 Состояния Portfolio на вкладке | соответствие «Состояниям и ошибкам Portfolio на клиенте» | isStale/загрузка/ошибка отображаются как на «Позициях» | component | Scenario «Состояния Portfolio на вкладке “Концентрация”»; сверка с canonical — существующий regression-прогон frontend |
|
||
| «Нормализованный состав Portfolio» (MODIFIED) | sector/issuer nullable; обрезка пробелов; только пробелы = отсутствие; sector только у STOCK/BOND/FUND; issuer.id+name; запрет эмитента по названию | Поля по правилам; сценарии 30–60 delta; GET-контракт не сломан | integration (configured HTTP tests) | PVΔ Scenario «Сектор инструмента доступен/отсутствует», «Эмитент позиции доступен/отсутствует», «Эмитент не определяется по названию», «Недоступность сектора и эмитента не нарушает Snapshot»; обратная совместимость GET — существующий contract-прогон |
|
||
| «Свежесть и fallback полного Portfolio Snapshot» (MODIFIED) | исключение: token-отказ при sector/brand = 400 INVALID_TBANK_TOKEN; сектор/бренд — last-known, обновление по «Обновление сектора и эмитента»; GET не ждёт T-Bank | Fallback не маскирует token-отказ; хранимые sector/brand читаются локально | integration | TC-META-002; существующий backend contract-прогон |
|
||
| «Обновление сектора и эмитента» (ADDED) | первый обход ≥24 ч после успеха; интервал из hourly-investment-sync; «не найдено» тоже успех | Сценарии 149–152: значение обновляется в первый обход после 24 ч | integration | TC-META-003 |
|
||
| «Результат получения сектора и эмитента» (ADDED) | 4 строки таблицы: значение / нет значения / другой инструмент / иная ошибка; каждая — поле + отсчёт 24 ч | Каждая строка: точное поле и отсчёт (сценарии 170–202, включая перезапуск отсчёта от «не найдено») | integration | TC-META-004 |
|
||
|
||
## Negative and Boundary Focus
|
||
|
||
- Границы элементов: 1 / 5 / 6 / 7 (строки и метрика топ-5) — TC-CONC-016.
|
||
- Границы стоимости: 0 (исключена и не в N), отрицательная (в N только своей валюты),
|
||
`null` (в N в любой валюте), крайне малая доля «< 0,1 %» — Scenario «Отрицательная и неоценённая»/«Нулевая стоимость»/«Сноска о не учтённых позициях», TC-CONC-020.
|
||
- Округление: точная половина вверх (6,25 → «6,3»), сумма показанных ≠ 100 % — TC-CONC-020.
|
||
- Валютные границы: единственная валюта (Select скрыт), валюта только отрицательной
|
||
позиции (есть в выборе, разрез пуст), валюта пропала после обновления — Scenario «Доступные валюты вкладки», TC-CONC-015.
|
||
- Тайбрейки: равные суммы (цифры/латиница/кириллица), граница 5-й строки, равные
|
||
`currentValue` у одного `issuer.id`, одинаковые `issuer.name` при разных `id` — Scenario «Порядок элементов с равной суммой»/«Название эмитента при разных названиях», TC-CONC-008.
|
||
- 24h-отсчёт: успех → сброс; «не найдено» → сброс; иной инструмент / иная ошибка →
|
||
без сброса, повтор каждый обход; систематический сбой дольше 24 ч — TC-META-003/004.
|
||
- Запрещённые эффекты: GET не запускает T-Bank, sector/brand не освежают Snapshot,
|
||
enrichment не отменяет финансовый успех, «Прочее»-раскрытие не меняет топ-5 и диаграмму,
|
||
строка не ведёт на другую страницу — TC-META-002, Scenario «Раскрытие “Прочее”», «Нажатие на строку акции».
|
||
|
||
## Cross-system Verification
|
||
|
||
T-Bank → sync → хранилище → GET → frontend. Каждый F-сценарий failure-model:
|
||
|
||
| ID | Проверка | Test cases |
|
||
| --- | --- | --- |
|
||
| F01 | Финансовый отказ не замещается успехом sector/brand; прежний Snapshot | TC-META-002, TC-REG-004 |
|
||
| F02 | Иная ошибка: прежнее значение/`null`, отсчёт не меняется | TC-META-004 |
|
||
| F03 | Сбой любого звена цепочки инструмента → бренда — как F02; поля независимы | TC-META-004 |
|
||
| F04 | «Не найдено»/пусто/пробелы → `null` + сброс отсчёта | TC-META-004 + PVΔ Scenario «Ответ без значения заменяет известное значение» |
|
||
| F05 | Чужой UID/asset_uid → прежнее значение, повтор | TC-META-004 |
|
||
| F06 | Частичное обогащение: Snapshot публикуется целиком, группы наравне | PVΔ Scenario «Недоступность сектора и эмитента не нарушает Snapshot», Scenario «Позиции без эмитента в топе» |
|
||
| F07 | RESOURCE_EXHAUSTED → как F02 после повторов клиента; (квоты — Q-F3) | TC-META-004 |
|
||
| F08 | Token-отказ при sector/brand → 400 INVALID_TBANK_TOKEN, без fallback | TC-META-002, TC-REG-004 |
|
||
| F09 | Отказ публикации: нет ложного `lastSuccessfulAt` | TC-META-002 |
|
||
| F10 | Отказ сохранения sector/brand: поле и отсчёт прежние, финансовый успех цел | TC-META-003 |
|
||
| F11 | Смена/удаление подключения: 404/409/400, sector/brand не переходят в новое | TC-META-005, TC-REG-004 |
|
||
| F12 | Ошибка HTTP-чтения на клиенте: вкладка скрыта, данные не теряются | TC-CONC-002 |
|
||
| F13 | Старый JSON без `sector`/`issuer` → `null`, группы «не указан» | PVΔ Scenario «Недоступность сектора и эмитента не нарушает Snapshot», Scenario «Позиции без эмитента в топе» |
|
||
| F14 | Время sector/brand не освежает Snapshot; неполное `meta` — одно сообщение | TC-META-002; Scenario «Неполный Portfolio» |
|
||
| F15 | Пустой разрез: нет NaN и фиктивных 100 % | Scenario «Валюта только у отрицательной позиции» |
|
||
| F16 | Сбой дольше 24 ч: значение остаётся, повтор каждый обход | TC-META-003 |
|
||
|
||
Инварианты data-mapping: сумма разреза = сумма учитываемых позиций; доли в сумме
|
||
ровно 100 % (точные); отсутствие подстановки нуля вместо `null` — точные доли Scenario «Расчёт долей» и прогоны TC-CONC-007/016.
|
||
|
||
## Test Data and Environment Needs
|
||
|
||
- **Портфель (мультивалютный, ≥10 позиций):** акции ≥7 (для «Прочее»), ровно 6 и 5
|
||
вариантов; облигации; ≥2 фонда; позиция `CURRENCY`; `FUTURE`/`OTHER` для исключения.
|
||
Валюты: RUB + USD (два Select-варианта), одиночный RUB-вариант отдельным набором.
|
||
- **Стоимости:** положительные, 0, отрицательная, `null` (в т.ч. в невыполненной валюте);
|
||
1 RUB против 100 000 000 RUB («< 0,1 %»); пары с равными суммами (граница топ-5).
|
||
- **Бренды:** один `issuer.id` с разными `issuer.name` и разными суммами; равные суммы;
|
||
два `issuer.id` с одинаковым `issuer.name`; акции + облигации одного бренда; позиции
|
||
без бренда (группа «Эмитент не указан»).
|
||
- **Секторы:** каждый из 11 кодов таблицы PC:374 (минимум `it`, `government`, `energy`),
|
||
неизвестный код (`other`), пустой/пробельный, отсутствующий; один сектор у разных типов
|
||
(STOCK+BOND+FUND); ≥6 секторов для «Прочее» в «Секторах».
|
||
- **Upstream-моки (integration):** ответы T-Bank для всех 4 исходов таблицы «Результат получения сектора и эмитента»
|
||
(значение / «не найдено» NOT_FOUND и пустой объект / чужой UID / UNAVAILABLE-timeout /
|
||
PERMISSION_DENIED-token), частичный ответ, отказ публикации; `meta` неполноты.
|
||
- Окружение: локальное backend + frontend с тестовым T-Bank-подключением; для Q-D1/Q-D2/Q-F3 —
|
||
read-only доступ к реальному токену владельца.
|
||
|
||
## Manual / Exploratory Scope
|
||
|
||
- Соответствие макетам ux-design v2 (`visuals/`): кольцевая диаграмма, центр, бары строк,
|
||
«Прочее», предупреждение — по всем четырём разрезам.
|
||
- Контраст тёмной/светлой темы: сегменты, подписи, «< 0,1 %», сноска.
|
||
- Клавиатура: Tab по переключателям разрезов, строкам и «Прочее»; Enter/Space раскрытие
|
||
(PC:254), видимый focus, отсутствие «клик-ловушек».
|
||
- Скринридер (VoiceOver/NVDA): текстовый эквивалент диаграммы — название, сумма, доля
|
||
каждого сегмента в порядке списка; центр; сопоставление сегмент↔строка без цвета (PC:443).
|
||
- Русская локаль чисел: неразрывный пробел, `₽`/`$`, запятая в долях.
|
||
- Exploratory: поведение при переключении счёта, глубоких ссылок на вкладку (если есть),
|
||
медленной сети при раскрытии «Прочее».
|
||
|
||
## Automation Candidates
|
||
|
||
- Компонентный вычислитель разреза (состав, ранжирование, тайбрейки, доли, границы 5/6/7,
|
||
формат долей) — чистая функция от Portfolio: детерминированные оракулы из сценариев,
|
||
максимум ценности на единицу поддержки.
|
||
- Интеграционные проверки таблицы исходов «Результат получения сектора и эмитента» и 24h-логики (управляемое время) —
|
||
регрессионно-критичны, зависят от классификации ошибок клиента.
|
||
- e2e smoke: вкладка есть/нет, reset/persist состояния, отсутствие навигации по строкам,
|
||
одно «Данные неполные».
|
||
|
||
## Regression Impact
|
||
|
||
| Область | Риск | Проверка |
|
||
| --- | --- | --- |
|
||
| Вкладка «Позиции» существующего счёта | Вкладки/состояния страницы изменены | TC-REG-001: прежний дефолт, состав и порядок вкладок |
|
||
| PortfolioStructure («Структура портфеля») | Общий выбор валюты «протекает» на вкладку | TC-CONC-015; существующий regression-прогон PortfolioStructure |
|
||
| GET-контракт Portfolio | Новые поля sector/issuer ломают клиентов; старый JSON | Существующий backend contract-прогон (OpenAPI); обратная совместимость ответа |
|
||
| Часовой обход hourly-investment-sync | Новые вызовы сектора/бренда меняют нагрузку и успех обхода | TC-REG-004: успех/причины обхода без sector/brand-сбоев; F07/F11 |
|
||
| Инвалидация token | Новое ветвление token-отказа | TC-META-002/005: 400 INVALID_TBANK_TOKEN во всех точках, замена/удаление подключения — 404/409 |
|
||
|
||
## Entry / Exit Criteria
|
||
|
||
Вход: G2 approved (есть); design готов или проверка не зависит от него (component-
|
||
вычислитель и integration по спекам можно начинать); тестовые данные раздела выше доступны.
|
||
Выход: все строки Coverage Matrix зелёные либо явные `not verified` ниже; все F01–F16
|
||
покрыты; регрессия TC-REG-001/004 и существующие contract/regression-прогоны пройдены; ручной блок (макеты, контраст, клавиатура,
|
||
скринридер) зафиксирован; findings по Q-D1/Q-D2/Q-F3 записаны.
|
||
|
||
## Gaps / Blockers
|
||
|
||
- not verified: соответствие квотам T-Bank при суточном обходе — риск деградации
|
||
синхронизации; закрывается Q-F3 (измерение на реальном токене), норма исходов от
|
||
результата не зависит.
|
||
- not verified (до реализации): фактический вид «не найдено» у `EtfBy`/`BondBy`/`GetAssetBy`
|
||
(Q-F3) — до подтверждения классификация NOT_FOUND в проверках задаётся моком по proto;
|
||
расхождение с реальностью выявит Q-F3-проверка.
|
||
- Открытый data-fact: Q-D1 (покрытие brand-пары) и Q-D2 (реальные `sector` фондов и
|
||
госбумаг) — одноразовые read-only проверки на реальном Portfolio владельца; влияют на
|
||
ожидаемый вид разрезов, не на нормы. Результат фиксируется в QA-отчёте change.
|
||
- Пробелов в Specs, блокирующих проверку, нет (после G2 approved).
|