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

Примеры в этой статье написаны на языке 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`, по которому можно найти то место, в котором возникла ошибка и попробовать его проанализировать.

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

Нужна помощь? Связаться с нами Связаться с нами