Знаете, когда знаешь, как решить баг, но как-то долго на это тратишь? Только чтобы понять, что ты все время ошибался и что решение было другим?
Что ж, вы можете поблагодарить Предвзятость подтверждения.
Это ловушка!
Я создаю Nodejs CRUD с TDD для учебных целей. И я добрался до теста базы данных.
Тест создает поддельные данные, сохраняет их с помощью Mongoose и запускает тест, используя созданные данные. После всех тестов коллекция (где все данные) стирается автоматически.
Я успешно сделал все вышеперечисленное, кроме части стирания коллекции. Каким-то образом поддельные данные, созданные в начале теста, были стерты до его окончания.
Mocha (тестовый фреймворк) имеет хук под названием «after()». И он делает именно то, что заявлено: он запускается после всех тестов. Но каким-то образом коллекция стиралась до конца! Поэтому я подумал: «Я, наверное, не знаю, как работает крючок Mocha».
Для этого я забрел в документацию к хуку, но это никуда меня не привело. Не поймите меня неправильно, документация великолепна, но я не нашел ничего о after(). Он только констатировал очевидное: он запускается после всех тестов.
Я начал думать, что на Mocha есть ошибка. Я имею в виду, что шансы на то, что фреймворк ошибается, выше, чем мы ошибаемся. (Мы все так думали раньше, верно?)
После более чем часа (я замерил время), пытаясь решить эту проблему, я устал. Не знаю как, но я начал думать, что может проблема не в хуке, а в функции Mongoose.
Я нашел эту функцию в вопросе StackOverflow и вспомнил, что есть два способа стереть коллекцию. Затем я адаптировал второй к своему тесту, и он сработал! Просто как тот. Мои тесты прошли гладко, без ошибок.
Вывод
Я пришел к одному выводу: я чертовски тупой! Нет, я просто шучу. Ответ не так прост.
Что случилось?
Меня ослепила предвзятость подтверждения.
Я был настолько уверен, что проблема в хуке «after()», что оказался недальновидным. Я не мог видеть ничего, кроме этой проблемы. И чем больше я искал (ничего не находя), тем больше закрывался от других решений.
Теперь все понятно. Проблема заключалась в том, что функция, которую я использовал, была асинхронной:
//classes is the collection's name
mongoose.connection.collections["classes"].drop((error)=>{
if(error){
console.log(`Drop collection error: ${error}`)
}
})
Неудивительно, что база данных была стерта до окончания теста! И я знал, что Мангуст вернул Обещания! Но опять же, я был слишком сосредоточен на решении того, что я считал проблемой, что упустил даже это. Я даже подумал, что проблема в Мокке.
Извини, Мокко, ты прекрасен!
Когда мы ослеплены предвзятостью подтверждения, это всегда вина кого-то другого. Никогда не наш.
Если эта история находит отклик у вас, вы не одиноки. Я думаю, что все мы, программисты, часто сталкиваемся с этой проблемой. Итак, чтобы помочь нам не попасть в эту ловушку снова, я придумал 4 шага, которым нужно следовать при отладке. Я надеюсь, что они действительно помогут вам.
Предотвращение предвзятости подтверждения
Шаги:
- Разбейте функцию.
- Выберите 2 детали, которые, по вашему мнению, могут быть причиной проблемы.
- Установите таймер обратного отсчета, чтобы найти их решение.
- Поиск.
Объяснение
- Разбейте логику кода, чтобы его было легче понять.
- Эта часть является наиболее важной для предотвращения предвзятости подтверждения. Вы пытаетесь решить ошибку и, вероятно, уже думали о возможном решении. Чтобы не застрять на этом навсегда, вы также выберете другое возможное решение.
- Это дополняет последний пункт. Установите таймер обратного отсчета, чтобы избежать вечного поиска единственного решения, которое, по вашему мнению, решит проблему. Я мог бы быть одним помодоро
- Иди ищи!
Заходите ко мне на мою (простую, но любимую) домашнюю страницу, чтобы узнать больше о программировании и психологии.