фото Bart Christiaanse. на Бессмысленно
Мы все прошли через следующий сценарий: вы получаете первый глоток вашего кофе, когда кто-то сообщает об ошибке. Ваша первая реакция, вероятно, для запуска проекта и введите некоторые журналы, чтобы увидеть некоторые данные и попытаться понять, что происходит.
Если вы похожи на 80% разработчиков (я составил этот номер), у вас нет каких-либо тестов, и вы в основном делаете настройки «надеясь», что ничего больше не разрывается, пока вы исправите проблему, и если это произойдет в конечном итоге проводить больше времени, чем вы ожидали, исправляя эти привязанные ошибки.
Давайте ясно, я не здесь, чтобы сказать вам, что у вас должны быть тесты и отличное покрытие кода, каждый проект отличается, и вы можете иметь более одной причины не иметь тестов. Вероятно, вы не работали над этой функциональностью, подумали, что поведение было настолько простым, что тесты были излишне, или вам пришлось спешить, чтобы сделать его до конца спринта.
Что бы ни в том, что эта проблема дает вам второй шанс добавить тесты, которые будут сэкономить вас и будущим разработчикам много времени. Мне нравится думать об испытаниях как Детекторы дыма в доме и ошибка – это огонь, который появился, вы могли бы потушить огонь Но если у вас нет достаточно детекторов дыма, вы не будете знать, готовит ли другие пожары где-то еще, пока не поздно.
фото Адам Уилсон на Бессмысленно
Toothmate сообщил, что входы URL в наших формах, где принимают строки, которые не были действительными URL. В основном вы можете ввести что-то вроде foobarhttps://google.com,+fizbuzz
и проверка прошла. Нам удалось определить виновник:
function validUrl(url) { const regex = /(^$)|((http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*))/g; const found = url.match(regex); if (found === null) { return false; } return true; }
Кто-то в основном копирует/наклеил регельс откуда-то, проверил его против некоторых URL-адресов и не URL, и думал, что это сработало. После штамповки это регулярное выражение в Regextester.com ясно, что шаблон не строги И это своего рода включает в себя шаблон.
После некоторого регулятора Regex мы выяснили способ сделать его более строгим и заканчиваться таким:
/( ^(((http(s)?:\/\/.)?(wwwwww az0-9 @:%._+ ~#=] (2,256) ] {2,6} \ b ([- a-za-z0-9 @:% _ +. ~ #? &/=] *)) $)/G
Мы проверили его на инструменте Regex и, кажется, работают.
Теперь мы просто заменим эту линию кода и отправить ее правильно? НЕПРАВИЛЬНО!
Прежде чем делать какие-либо изменения кода, мы пишем некоторые тесты для сценариев, которые мы знаем, должны работать:
describe("validUrl", () => { it("should not return errors with an empty string", () => { const actual = validUrl(""); const expected = true; expect(actual).equal(expected); }); it("should not return errors with a well formed URL", () => { const actual = validUrl("https://google.com"); const expected = true; expect(actual).equal(expected); }); it("should return an error with something that is not a url", () => { const actual = validUrl("not-a-url"); const expected = false; expect(actual).equal(expected); }); it("should return an error if empty spaces ares used", () => { const actual = validUrl(" "); const expected = false; expect(actual).equal(expected); }); });
Если вы не хотите читать/понимать, что код в основном мы проверяем, что:
- Когда он получает пустую строку, это действительно (у нас есть функция требуется, если она не должна)
- Хорошо сформированные URL-адреса действительны
- То, что не является URL, должен вернуть ложь
- Использование пробелов также не допускается
Теперь мы добавляем новый неудачный тестовый корпус, URL с дополнительным текстом не должен потерпеть неудачу:
it("should return an error when a url has extra text", () => { const actual = validUrl("somethinghttp://google.com,other-thing"); const expected = false; expect(actual).equal(expected); });
Вот а кодепен так что вы можете следовать вдоль
Затем мы запускаем тесты, все они проходят, кроме последнего, потому что мы не изменили Regex, и это здорово, потому что мы подтвердили наши предположения, и мы сейчас находимся в красном цикле.
Мы заменяем регулярное выражение с новым /( ^(((http(s)?:\/\/.)?(wwwwww az0-9 @:%._+ ~#=] (2,256) ] {2,6} \ b ([- a-za-z0-9 @:% _ +. ~ #? &/=] *)) $)/G
Отказ
Помните, что это было единственное, что мы подумали, что нам нужно было исправить ошибку, а затем мы снова проводим тесты, ожидая, что все пройти, кроме них нет.
Удивительно наше регулярное выражение теперь настолько строги, что не позволяет пустыми строками, но наш Детектор дыма помешал нам отправить этот огонь, который мы не заметили. Это было бы пустой тратой времени для нас, тестеров, менеджера проекта и в худшем случае сценарий мог бы предотвратить запуск или вызвать катастрофическую проблему, если она развернута. Поскольку нам нужно позаботиться о краевом случае, мы решаем короткое замыкание с самого начала вместо того, чтобы поддерживать настройку Regex:
if (!url) { // empty string should be valid return true; }
Теперь мы зеленые! Мы можем продолжить рефакторинг и отправить наши изменения более уверенно.
Конечно, это не серебряная пуля, могут быть больше случаев по краям или изменениям требований. Преимущество в том, что когда это произойдет, вы или любой другой разработчик, который должен поддерживать проект, может продолжать добавлять Детекторы дыма И будьте уверены, что их изменения выдвигают огни и не жаждущие старые.
Оригинал: “https://dev.to/ederchrono/tdd-debugging-37hb”