Покрытие кода и тест-покрытие: субъективность и полезность |
03.10.2019 00:00 |
Автор: Дэн Эшби (Dan Ashby) Удивительно, сколько народу верит, что покрытие кода и тест-покрытие – это одно и то же. Не знаю, откуда растут ноги у этой путаницы, но судя по обсуждениям в интернете, взаимозаменяемость этих терминов – очень распространенная вещь, и люди, возможно, делают это и подсознательно. Но это не одно и то же. Возьму игрушку сына, чтобы объяснить. У моего сына Ангуса довольно давно есть игрушка-ходилка. Она помогла ему удерживать равновесие – сейчас, в возрасте 17 месяцев, он носится очень шустро, и нет сомнений, что в том есть заслуга игрушки. У этой игрушки есть отверстия разной формы сверху и с боков, и она идет в комплекте с блоками, подходящими для этих отверстий. Он обожает эту игрушку, и, наблюдая за его играми несколько месяцев, я осознал, что это отличный пример для объяснений различий и субъективности между покрытием кода и тестовым покрытием. Игрушка Вот так она выглядит: На картинке виден красный кирпичик. Он подходит к прямоугольному отверстию на боку игрушки. Используем игрушку как аналогию. Если взглянуть на отверстие как на код, отвечающий за фичу, а на кирпичик – как на данные, которые может ввести пользователь согласно этой фиче, то проталкивание кирпичика в отверстие покроет этот код. Это можно рассматривать, как стопроцентное покрытие кода. Мы протолкнули кирпичик в отверстие, и активировали 100% кода этой фичи. Однако если посмотреть на кирпичик пристальнее, можно заметить, что протолкнуть его в отверстие можно 16 различными способами. 16 способов вставить кирпичик У кирпичика шесть сторон – четыре боковых, верхняя и нижняя. Его можно вставить в отверстие каждой стороной разными способами:
Но помимо этого, его еще можно вставить по двум разным направлениям:
Итого 16 разных способов вставить кирпичик в отверстие, для которого он предназначен. В терминах тестирования, имея 16 известных тестов, мы получим, что наш единичный изначальный тест, потенциально дающий стопроцентное покрытие кода, дает всего лишь 6,25% тест-покрытия. Но это еще не все: тест-покрытие относится только к известным тест-идеям. Пока что мы придумали 16 тестов, и вы можете подумать, что прогон всех 16 даст нам стопроцентное тест-покрытие… Но ведь наверняка есть еще тесты, о которых мы еще не подумали. Вернемся к игрушке. У нее есть другие отверстия иной формы, и некоторые из блоков другой формы тоже можно вставить в наше прямоугольное отверстие. Причем с разных сторон! Видите квадратное отверстие на верхней части игрушки? Кубик, который подходит для него, также пролезает в прямоугольное отверстие. Этот кубик означает, что у нас добавляется еще 48 возможных способов протолкнуть предмет через прямоугольную дырку. Как можно видеть, метрики процента покрытия крайне субъективны и относятся исключительно к моменту времени и информации, известной на этот момент. Они ничего на самом деле не говорят о качестве вашего ПО или качестве вашего тестирования. Представьте, что мы с вами одновременно тестируем одну и ту же фичу на протяжении одного и того же времени, и действуем независимо друг от друга. Скорее всего, показатели нашего тестового покрытия будут отличаться – мы бы думали о разных тестах, и наверняка оставили бы за бортом некоторые неизвестные нам идеи тестирования, о которых мы не вспомнили из-за различающегося опыта, убеждений и предрассудков. И если бы по чистой случайности это число оказалось бы равным, оно все равно не уравнивало бы наше тестирование – оно бы очень и очень различалось. Эта ситуация просто замаскировала бы проблему и субъективность еще сильнее, и она хорошо освещает тот факт, что метрики покрытия не рассказывают нам о качестве приложения, качестве тестирования, и о том, а что вообще проверялось. Но от покрытия кода тоже есть польза Покрытие кода может вам пригодиться – оно сообщает об областях приложения, которые вообще не покрывались никакими подтверждающими тестами. Это риск, и его надо расценивать как приглашение исследовать эти непротестированные области. Проценты не имеют значения, но информация о том, какой код вообще не выполнялся – полезная эвристика. |