function testVector() {
var p1 = new Vector(10, 20);
var p2 = new Vector(-10, 5);
var p3 = p1.plus(p2);
if (p1.x !== 10) return "облом: значение x не то";
if (p1.y !== 20) return "облом: значение y не то";
if (p2.x !== -10) return "облом: отрицательное значение x не то";
if (p3.x !== 0) return "облом: результат сложения x не тот";
if (p3.y !== 25) return "облом: результат сложения y не тот";
return "всё пучком";
}
console.log(testVector());
// → всё пучком
Написание таких проверок приводит к появлению повторяющегося кода. К счастью, есть программные продукты, помогающие писать наборы проверок при помощи специального языка, приспособленного именно для написания проверок. Их называют testing frameworks.
Отладка (debugging)
Когда вы заметили проблему в программе (она ведёт себя неправильно и выдаёт ошибки), самое время выяснить, в чём проблема.
Иногда это очевидно. Сообщение об ошибке наводит вас на конкретную строку программы, и если вы прочтёте описание ошибки и эту строку, вы часто сможете найти проблему.
Но не всегда. Иногда строчка, приводящая к ошибке, просто оказывается первым местом, где некорректное значение, полученное где-то ещё, используется неправильно. Иногда вообще нет сообщения об ошибке – есть просто неверный результат. Если вы делали упражнения из предыдущих глав, вы наверняка попадали в такие ситуации.
Следующий пример пробует преобразовать число заданной системы счисления в строку, отнимая последнюю цифру и совершая деление, чтобы избавиться от этой цифры. Но дикий результат, выдаваемый программой, как бы намекает на присутствие в ней ошибки.
function numberToString(n, base) {
var result = "", sign = "";
if (n < 0) {
sign = "-";
n = -n;
}
do {
result = String(n % base) + result;
n /= base;
} while (n > 0);
return sign + result;
}
console.log(numberToString(13, 10));
// → 1.5e-3231.3e-3221.3e-3211.3e-3201.3e-3191.3e-3181.3...
Даже если вы нашли проблему – притворитесь, что ещё не нашли. Мы знаем, что программа сбоит, и нам нужно узнать, почему.
Здесь вам надо преодолеть желание начать вносить случайные изменения в код. Вместо этого подумайте. Проанализируйте результат и придумайте теорию, по которой это происходит. Проведите дополнительные наблюдения для проверки теории, а если теории нет – проведите наблюдения, которые бы помогли вам изобрести её.
Размещение нескольких вызовов console.log
в стратегических местах – хороший способ получить дополнительную информацию о том, что программа делает. В нашем случае нам нужно, чтобы n
принимала значения 13
, 1
, затем 0
. Давайте выведем значения в начале цикла:
13
1.3
0.13
0.013
...
1.5e-323
Н-да. Деление 13 на 10 выдаёт не целое число. Вместо n /= base
нам нужно n = Math.floor(n / base)
, тогда число будет корректно «сдвинуто» вправо.
Кроме console.log
можно воспользоваться отладчиком в браузере. Современные браузеры умеют ставить точку остановки на выбранной строчке кода. Это приведёт к приостановке выполнения программы каждый раз, когда будет достигнута выбранная строчка, и тогда вы сможете просмотреть содержимое переменных. Не буду подробно расписывать процесс, поскольку у разных браузеров он организован по-разному – поищите в вашем браузере “developer tools”, инструменты разработчика. Ещё один способ установить точку остановки – включить в код инструкцию для отладчика, состоящую из ключевого слова debugger
. Если инструменты разработчика активны, исполнение программы будет приостановлено на этой инструкции, и вы сможете изучить состояние программы.
Распространение ошибок
К сожалению, программист может предотвратить появление не всех проблем. Если ваша программа общается с внешним миром, она может получить неправильные входные данные, или же системы, с которыми она пытается взаимодействовать, окажутся сломанными или недоступными.
Простые программы, или программы, работающие под вашим надзором, могут просто «сдаваться» в такой момент. Вы можете изучить проблему и попробовать снова. «Настоящие» приложения не должны просто «падать». Иногда приходится принимать неправильные входные данные и как-то с ними работать. В других случаях нужно сообщить пользователю, что что-то пошло не так, и потом уже сдаваться. В любом случае программа должна что-то сделать в ответ на возникновение проблемы.