Какво е „добро“ покритие на кода? Практически наръчник

Разбивам мита за 100%: минавам през доказани цели за покритие при TypeScript и PHP, показвам възвръщаемостта от тестовете и споделям трикове с инструменти, които ползвам всеки ден.

Какво е „добро“ покритие на кода? Моят практически наръчник за спиране на бъгове, без да пилеем инженерно време

Всеки път, когато пусна npm run coverage или phpunit --coverage, изскача един и същ въпрос:

„Добре... 74%. Достатъчно ли е?“

Блогосферата за софтуерна разработка крещи „100% или нищо!“. Междувременно launchdarkly.com учтиво ми напомня, че 100% изпълнен код не е същото като 100% тестван код.
Прекарал съм седмици в гонене на лъскавата метрика и още повече седмици в дебъгване на други проблеми. Това е проверената в реална работа среда, на която съм се спрял.


Защо 100% покритие е мираж

На теория 100% изпълнение на редовете значи „няма скрити бъгове“. На практика:

  • Намаляваща възвръщаемост: 90%→95% често удвоява test suite-а ти за едноцифрено намаляване на риска.
  • Фалшива увереност: тест, който извиква функция без нито един assertion, пак се брои за покритие.
  • Бизнес реалност: всеки допълнителен тест е време, което не отива във функции, поискани от клиентите ти.

Хората в аерокосмическата индустрия могат да се целят в 100% — там е въпрос на живот и смърт. За останалите от нас ~80% е линията 80/20. Там се събират повечето проекти след изчисляване на възвръщаемостта. testdevlab.com посочва диапазона 70-90% точно по тази причина.


Практическата таблица, която използвам

Покритие Моят превод Действие
100% „Ние сме библиотека, която управлява ракети“ Приеми мъката.
90% + „Библиотека, от която зависят много пари“ Само за модул с висок приоритет.
80% Ship it, наблюдавай, после итерация.
60-70% Merge gate — проваляй PR-а, ако новият код те свали под това.
< 50% Уикенд технически дълг — първо завий към критичните пътища.

Откраднах тези числа от вътрешния наръчник на Atlassian: 60% „приемливо“, 75% „похвално“, 90% „примерно“. Работи във всяка ретроспектива.


Как стигам до 80%, без да плача (TypeScript playbook)

  1. Jest + Istanbul директно от кутията
  2. Праг за покритие в CI
    в jest.config.js добавям:
    coverageThreshold: {
      global: 80,
      '**/src/core/**': 90
    }
  3. Цели се в горещите потребителски пътища, не в Redux boilerplate logger-а.

Как стигам до 80% в Laravel (PHP playbook)

  1. Инсталирай PCOV за скорост в dev среда, Xdebug за branch данни в CI.
  2. PHPUnit + тези настройки по подразбиране в phpunit.xml:
    <filter>
      <whitelist processUncoveredFiles="true">
        <directory suffix=".php">./src</directory>
      </whitelist>
    </filter>
  3. Mutation score > брой редове чрез Infection — така хващам редовете „покрити, но не наистина тествани“.

4 правила, по които живее екипът ми

  1. Нов код = тестове. Diff coverage ≥ 90% преди merge.
  2. Първо рефакторирай, после тествай. Нетестваемият код вече е дълг.
  3. Проваляй build-а, не хората. Сваляй прага с 5% всяка година, вместо да чупиш екипи с червени dashboard-и.
  4. Мери бъговете в production — ако покритието е 85%, но инцидентите скачат, покритието не е виновникът; assertion-ите са.

TL;DR (и за ръководители, и за recruiter-и)

Не ме питай за „магическо число“. Попитай:

Кои части от продукта не могат да се счупят?

Покрий тях до 90%. Дай на останалото здрави smoke tests. Използвай code coverage като прожектор, не като финална линия, и вярвай на бъговете, които хващаш, не на числата, с които се хвалиш.

Нека coverage dashboard-ът бъде зелен — клиентите ти никога няма да го видят, но тяхната лента с грешки ще остане празна.

— Край на rant-а, обратно към editor-а.


Коментари

Boris D. Teoharov

Автор

Здравей, аз съм Борис

Не съм писател. Не съм философ. Просто съм backend инженер от България, който живее между Laravel опашки и индекси със стотици милиони редове. През останалото време чета медицина, която няма работа да чета, френски романи, които разбирам наполовина, и каквото още малката ми гумена глава реши да дъвче. Две спасени кучета ме държат честен.