Как найти ошибки в коде

Примеры в этой статье написаны на языке JavaScript, но принципы одинаковы для любого языка.

Код на Хекслете проверяется с помощью автоматических тестов. Обычно они написаны на том же языке, на котором написан сам код. Общий принцип работы такого вида тестирования довольно прост. Тестируемая программа загружается в память и вызывается с разными параметрами, а тесты следят за тем, чтобы ее поведение соответствовало ожидаемому.

Когда код не проходит тесты, то обычно говорят что тесты упали. В этот момент начинается самое интересное. Необходимо понять где и почему возникла ошибка. И вывод тестов в этом процессе играет ключевую роль, это главный помощник и проводник. Но необходим опыт, чтобы начать делать правильные выводы из того, что пишут тесты.

В первую очередь нужно классифицировать проблему. Ошибки в тестах можно грубо разделить на две категории. Первая – это ошибки, которые выдает компилятор или интерпретатор: синтаксическая ошибка, ошибка типизации и так далее. Вторая — это ошибочные утверждения.

Утверждения

Утверждение — это специальная функция, которая вызывает ваш код с определенными параметрами и проверяет, что он возвращает ожидаемый результат. Например:

assert(isPrime(3));
assert.equal(factorial(3), 6);

Самое важное: если тесты упали на утверждении, это означает, что ваш код как минимум отработал, но его результат не соответствует ожидаемому. Причем часто бывает так, что часть утверждений проходит проверку, то есть код возвращает правильный результат, а часть нет, обычно в пограничных случаях. В конечном итоге падение теста на утверждении говорит о том, что в коде логическая ошибка (ошибка в вычислениях).

Вывод в таком случае выглядит примерно так:

assert.js:89
  throw new assert.AssertionError({
  ^
AssertionError: 3 == 1
    at Object.<anonymous> (test.js:4:8)
    at Module._compile (module.js:413:34)
    at loader (/usr/local/lib/node_modules/babel-register/lib/node.js:126:5)
    at Object.require.extensions.(anonymous function) [as .js] (/usr/local/lib/node_modules/babel-register/lib/node.js:136:7)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at /usr/local/lib/node_modules/babel-cli/lib/_babel-node.js:161:27
    at Object.<anonymous> (/usr/local/lib/node_modules/babel-cli/lib/_babel-node.js:162:7)
    at Module._compile (module.js:413:34)

Вывод можно разделить на две части. Первая – это текстовое сообщение с описанием того, что ожидалось от функции и что было получено. Подробность вывода зависит от вида утверждения и возможностей тестовой среды. В коде выше это строка AssertionError: 3 == 1. Читается она следующим образом: «ожидалось, что функция вернет 3, но она вернула 1». Это уже хорошо, но еще хотелось бы увидеть, с какими параметрами была вызвана функция. И в этом нам поможет вторая часть вывода.

Вторая часть называется backtrace, она содержит список функций, которые последовательно вызывались в коде. Порядок вывода, чаще всего, обратный: в начале то, что вызывалось последним. В первую очередь нужно, начиная с конца, найти первое упоминание функции из файла, который похож на тестовый. Обычно его называние содержит слово test. В примере выше это строчка at Object.<anonymous> (test.js:4:8). В этой строчке всегда есть указание на строчку, на которой и будет вызов этого утверждения. В данном случае это строчка 4. Всё, что теперь остается, это зайти в соответствующий файл и посмотреть то, как вызывалась ваша функция.

Предупреждения компилятора/интерпретатора

Синтаксические ошибки

Самый простой тип ошибок, говорит о том что вы ошиблись в синтаксисе. Забыли запятую, скобку и тому подобные вещи. Такие ошибки легко находить и исправлять. Синтаксическая ошибка сопровождается текстом по которому можно загуглить возможные причины.

Другие ошибки

Большой класс ошибок, которые могут возникать в процессе разработки. В выводе всегда присутствует сообщение об ошибке, которое очень важно понять. Это то самое место, где происходит очень много гугления. Также эти ошибки содержат вывод backtrace, по которому можно найти то место, в котором возникла ошибка и попробовать его проанализировать.

Многие из этих ошибок легко исправить с помощью отладочной печати (см. урок «Отладочная печать» в курсе Основы программирования).

Была ли эта статья полезна? Спасибо за оценку! Возникла проблема при отправке оценки. Попробуйте позже

Нужна помощь? Напишите нам Напишите нам