Например: при выполнении функционального тестирования формы в веб-приложении мы будем проверять поля, вводя различные виды случайных входных значений.
Как правило, мы, пользователи веб-приложения, не вводим случайные значения в поля.
Так какая польза от включения всех тех тестовых случаев, которые могут / не могут привести к ошибкам, когда вероятность появления такого рода проблем в производстве намного меньше?
Примечание: приведенный выше пример является только примером; Такие проблемы могут возникнуть в любой функции / модуля.
Я задаю этот вопрос только для того, чтобы узнать, нужно ли следовать каким-либо стандартным методам или это полностью зависит от продукта, домена и всех других факторов.
testing
web-applications
bug
Нагарани Дуббака
источник
источник
Ответы:
Вы не можете вводить случайные значения в поля веб-приложения, но, безусловно, есть люди, которые делают именно это.
Некоторые люди вводят случайно случайно, а другие делают это намеренно, пытаясь сломать приложение. В обоих случаях вы не хотите, чтобы приложение зависало или демонстрировало другое нежелательное поведение.
Для пользователей первого типа вы не хотите этого, потому что это дает им плохой опыт и может отвергнуть их.
Что касается пользователей второго типа, они обычно не имеют честных намерений, и вы не хотите, чтобы у них был доступ к информации, к которой у них не должно быть доступа, или не позволяли бы им лишать подлинных пользователей доступа к вашим услугам.
Стандартная практика тестирования заключается в проверке не только того, что случай в хорошую погоду работает, но также и того, что исследуются необычные крайние случаи, чтобы найти потенциальные проблемы и быть уверенными, что злоумышленники не смогут легко получить доступ к вашей системе. Если ваше приложение уже аварийно завершает работу со случайным вводом, вы не хотите знать, что может сделать злоумышленник с помощью специально созданного ввода.
источник
Никогда не принимай ничего
Вы не можете предполагать, что какой-либо пользователь не будет делать что-то «глупое» с вашим программным обеспечением случайно или преднамеренно. Пользователи могут случайно нажать не ту кнопку, кошка может ходить по клавиатуре, система может работать со сбоями, их компьютер может быть взломан вредоносным программным обеспечением и т. Д.
Кроме того, сами пользователи могут быть злонамеренными, преднамеренно ища способы взломать ваше программное обеспечение в надежде, что они могут найти способ использовать его в своих интересах. Даже если они обнаружат ошибку, которую они не смогут использовать, все, что они найдут, может подтолкнуть их к проверке вашей системы на предмет того, что они могут атаковать, зная, что в ваших процедурах контроля качества отсутствуют.
Что касается тестирования, полезно защититься от случайных входных данных, однако выбор тестовых входных данных полностью случайным образом (т. Е. Без какого-либо особого внимания к любому варианту использования или крайним случаям) граничит с бесполезным. Целью тестирования является проверка вашего решения на соответствие требованиям и ожиданиям вашего работодателя / клиентов / пользователей; это означает, что вам нужно сосредоточиться на нацеливании на все граничные случаи и граничные условия, а также на любые «вырожденные» случаи, которые не соответствуют ожидаемому рабочему процессу пользователя.
Конечно, вы можете запускать тесты, которые выявляют ошибки, которые, по вашему мнению, не стоит исправлять; это может быть по разным причинам - ошибка может быть слишком дорогой, чтобы ее можно было исправить по сравнению с ее влиянием на пользователя, или вы можете обнаружить ошибки в функциях, которые никто не использует, или ошибка может быть уже настолько хорошо внедрена в систему, что некоторые пользователи рассматривают это как особенность.
В качестве альтернативы, вы можете писать какое-то специальное программное обеспечение, которое имеет ограниченную аудиторию «опытных» пользователей, где нет коммерческой выгоды тратить время на исправление ошибок, потому что эти пользователи способны выполнять свою работу с ошибочным программным обеспечением (например, диагностическим инструментом). используемая внутренней ИТ-командой не приносит никакого дохода, поэтому, если он иногда дает сбой, то никто, скорее всего, не захочет платить за время, необходимое для его исправления - они просто скажут ИТ-команде, что вместо этого придется жить с ошибками) ,
Однако вы можете принимать эти решения только в том случае, если знаете об этих ошибках. Например, пользователь может ввести вредоносный ввод, который стирает всю базу данных - если вы явно не защищались от этого сценария и не тестировали его, то вы не можете быть уверены, может ли это произойти. Риск оставлять необнаруженные ошибки в системе означает, что вы потенциально можете оставить себя открытыми для реальных проблем, если одна из этих ошибок обнаружится в реальном мире и окажет серьезное влияние на ваших пользователей.
Таким образом, в то время как решение о том, исправлять ли ошибки, может потребовать некоторой информации от владельца программного обеспечения (обычно от того, кто платит вам зарплату), решение о том, проверять ли ошибки и какие случаи проверять, является инженерной проблемой, которая должна быть решена. учитывается в оценках и планировании проекта, где цель должна заключаться в том, чтобы обеспечить максимально приближенное к полному охвату, насколько это возможно, учитывая ограничения по времени / деньгам / ресурсам.
источник
For example, a user may enter a malicious input which wipes the entire database - if you haven't explicitly protected against and tested for this scenario, then there's no way you can be sure whether or not this can happen.
Как маленькие Бобби Таблицы из этого комикса XKCD? ;)Есть несколько факторов, которые необходимо учитывать. Чтобы проиллюстрировать эти моменты, я буду использовать пример поля, в котором пользователь должен вводить процент в контексте квоты, определенной для конкретной задачи, с точки зрения того, сколько дискового пространства может использовать эта задача. 0% означает, что задача не сможет записать что-либо на диск; 100% означает, что задача может заполнить все дисковое пространство. Значения между ними означают, что они значат.
Как разработчик, вы, вероятно, считаете, что допустимые значения [0, 1, 2, 3, 99, 100], а все остальное глупо. Давайте посмотрим, почему пользователи все еще могут вводить эти «глупые» значения.
Опечатки
%^
Пользователь вводил значение 56, но ошибочно нажимал Shiftпри их вводе (например, потому что на французской клавиатуре приходится нажимать Shiftдля ввода цифр, а пользователь постоянно переключался между французской клавиатурой и QWERTY).
Таким же образом вы можете получить число, с чем-то после или до него, или между:
56q
Здесь пользователь, вероятно, вводил цифры, а затем вкладку для перехода к следующему полю. Вместо нажатия ⇆ пользователь нажал соседнюю клавишу.
Непонимание и неправильное толкование
Пустой ввод, вероятно, самый обычный. Пользователь вообразил, что поле является необязательным, или не знал, что поместить в это поле.
56.5
Пользователь думал, что значения с плавающей запятой были приемлемы. Либо пользователь ошибается, и приложение должно вежливо объяснить, почему принимаются только целочисленные значения, либо были неверны начальные требования, и имеет смысл позволить пользователям вводить значения с плавающей запятой.
none
Пользователь неправильно понял, что при запросе места, которое может занять задание, приложение ожидало число. Это может указывать на плохой пользовательский интерфейс. Например, запрос пользователя «Сколько места на диске должно занимать задание?» Приглашает к такому типу ввода, в то время как поле с последующим знаком процента получит меньше такого рода ввода, потому что «none%» не делает много смысла.
150
Пользователь неправильно понял, что означает процент в данном случае. Возможно, пользователь хотел сказать, что задача может занять 150% используемого в настоящее время пространства, поэтому, если на диске объемом 2 ТБ используется 100 ГБ, задача может использовать 150 ГБ. Опять же, лучший пользовательский интерфейс может помочь. Например, вместо того, чтобы иметь пустое поле ввода со знаком процента, к нему можно добавить следующее:
Когда пользователь начнет печатать, он на лету изменит текст, чтобы он стал таким:
Представления
Большие числа или числа с плавающей точкой могут быть представлены по-разному. Например, число 1234,56 может быть записано так:
1,234.56
. В зависимости от культуры текстовое представление одного и того же номера будет отличаться. Во французском же номер будет записан следующим образом:1 234,56
. Видите, запятая, где вы не ожидаете, и пробел.Всегда ожидая, что конкретный формат с использованием определенной локали рано или поздно доставит вам неприятности, потому что у пользователей из разных стран будут разные привычки писать цифры, даты и время и т. Д.
Люди против компьютеров
Twenty-four
Обычные люди не думают так же, как компьютеры. «Двадцать четыре» - это фактическое число, независимо от того, что ПК скажет вам.
Хотя (1) большинство систем вообще не обрабатывают этот тип ввода и (2) почти каждый пользователь не представляет ввода целыми буквами, это не означает, что такой ввод глупый. В « О лице 3» Алан Купер подчеркивает, что отсутствие обработки таких входных данных указывает на неспособность компьютеров адаптироваться к людям, и в идеале интерфейс должен иметь возможность правильно обрабатывать эти входные данные.
Единственное, что я должен добавить к книге Алана Купера, это то, что во многих случаях числа пишутся цифрами по ошибке . Тот факт, что компьютеры ожидают от своих пользователей ошибок (и не потерпит того, кто пишет правильно), раздражает.
Unicode
5𝟨
Unicode оставляет за собой свои сюрпризы: символы, которые могут выглядеть одинаково, не одинаковы. Не убежден? Скопируйте и вставьте
"5𝟨" === "56"
в инструменты разработчика своего браузера и нажмите Enter.Причина того, что эти строки не равны, заключается в том, что символ Unicode отличается
𝟨
от символа6
. Это создаст ситуацию, когда разъяренный клиент позвонит, сообщив, что ваше приложение не работает, предоставив снимок экрана с вводом, который выглядит правдоподобно, и ваше приложение заявит, что ввод недействителен.Вы спросите: зачем вводить символ Unicode, который выглядит как цифра? Хотя я не ожидал, что пользователь введет один из них непреднамеренно, копирование-вставка из другого источника может привести к этому, и у меня был случай, когда пользователь фактически делал такую вставку-копирование строки, содержащей символ Unicode, который не появляются на экране.
Заключение
Это те случаи, которые вы получаете для поля ввода элементарного числа. Я позволил бы вам представить, что вы можете обрабатывать для более сложных форм, таких как дата или адрес.
Мой ответ сфокусирован на том, что вы назвали «глупым» вкладом. Тестирование не о проверке счастливых путей; это также проверка того, что ваше приложение не ломается, когда злонамеренный пользователь намеренно вводит странные вещи, пытаясь их сломать. Это означает, что, когда вы запрашиваете процент, вам также необходимо проверить, что происходит, когда пользователь отвечает строкой, содержащей 1 000 000 символов, или отрицательным числом, или таблицей бобби .
источник
1 234,56
строку (используя U + 00A0 NO-BREAK SPACE вместо U + 0020 SPACE), что является правильным способом кодификации этих числовых маркеров (или с помощью U + 202F). NARROW NO-BREAK SPACE, peroahps). Копирование значения из любого приложения, которое форматирует числа в соответствии с языковым стандартом, перед тем, как представить его пользователю, очень легко это произведет.Здесь есть много хороших ответов, которые описывают, почему это важно, но не так много советов о том, как разумно защитить ваше приложение. «Стандартная практика» - использовать надежную проверку входных данных как на клиенте, так и на сервере. Нечувствительный ввод легко защищать от; вы просто отвергаете все, что не имеет смысла в этом конкретном контексте. Например, номер социального страхования состоит только из тире и цифр; Вы можете безопасно отказаться от всего, что пользователь вводит в поле номера социального страхования.
Существует два вида тестирования, которые должны выполняться в каждом приложении, которое вы пишете, и у каждого из них разные цели. Тестирование, которое вы проводите на собственном приложении, является положительным; его цель - доказать, что программа работает. Тестирование, которое тестеры дополнительно выполняют в вашем приложении, является отрицательным; его цель - доказать, что ваша программа не работает. зачем вам это? Потому что вы не самый лучший человек для тестирования своего программного обеспечения. В конце концов, вы написали эту вещь, так что, очевидно, она уже работает, верно?
Когда вы пишете подтверждение ввода, вы будете использовать положительные тесты, чтобы доказать, что ваша проверка работает. Тестеры будут использовать случайные входные данные, чтобы доказать, что это не работает. Обратите внимание, что проблемное пространство для случайных входов по существу не ограничено; Ваша цель состоит не в том, чтобы проверить каждую возможную перестановку, а в том, чтобы ограничить пространство проблемы, отклонив неверный ввод.
Также обратите внимание, что конечный пользователь не единственный, кто предоставляет информацию для вашей программы. Каждый класс, который вы пишете, имеет свой собственный API и свои ограничения на то, что считается допустимым вводом, поэтому надежная проверка (например, «контракты кода») важна и для ваших классов. Идея состоит в том, чтобы укрепить ваше программное обеспечение таким образом, чтобы неожиданное поведение было редким или вообще отсутствовало в максимально возможной степени.
Наконец, рабочий процесс важен. Я видел падение приложений не потому, что пользователь ввел что-то бессмысленное, а потому, что они делали что-то в приложении в неожиданном порядке. Ваше приложение должно знать об этой возможности и либо изящно обрабатывать непредвиденные рабочие процессы, либо требовать от пользователя выполнения операций в указанном вами порядке.
источник
Обычно «случайные» значения не являются случайными. Вы пытаетесь захватить крайние случаи, «неизвестное неизвестное».
Скажем, например, что символ # вылетит из вашего приложения. Вы не знаете этого заранее, и было бы невозможно написать контрольные примеры для каждого возможного ввода. Но мы можем написать тест
"¬!"£$%^&*()_+-=[]{};'#:@~,./<>?|\"
и посмотреть, сломается ли онисточник
Однажды я написал программу, которую я тестировал в лаборатории с 60 студентами. Я стоял за 60 экранами компьютеров и видел, как они его используют. Количество нелепых поступков, которые они совершали, было невероятным. Я обливался потом, наблюдая за их «творчеством». Они сделали гораздо больше, чем любой отдельный человек может придумать в течение жизни. Конечно, один из них сломал это.
После этого я придерживаюсь подхода:
if "a very specific use case" do, else show error
Если у меня есть несколько вариантов использования, я строго определю их и приведу вышеизложенное.
источник
То, что вы описываете, это Fuzzing или Fuzz Testing : выбрасывайте случайные и неверные данные в систему и смотрите, что происходит. Вы не делаете этого, потому что ожидаете, что пользователь сделает это. Вы делаете это, чтобы выставить свои собственные предположения и предубеждения, чтобы подчеркнуть границы вашей системы, чтобы увидеть, что происходит.
Обычные тестовые данные, написанные человеком, будут содержать предположения и предубеждения. Эти смещения могут быть определенными классами ошибок, которые никогда не будут обнаружены при тестировании.
Например, если большая часть вашего ввода находится в ASCII-безопасном диапазоне Юникода, предположения о кодировке символов в коде не выполняются. Или, может быть, он всегда ниже определенного размера, поэтому поле или буфер фиксированного размера не удаляются. Или, может быть, есть специальные символы, которые интерпретируются удивительным образом, показывая, что пользовательский ввод передается в оболочку или используется для небезопасного построения запросов. Или, может быть, слишком много «счастливого пути» тестирования и недостаточно попыток для обработки ошибок.
Fuzzing не имеет таких предвзятых мнений о вводе. Это будет жестоко тренировать вашу систему с любой возможной комбинацией «правильного» ввода. Unicode, ASCII, большие, маленькие, и много-много ошибок. Ваша система должна изящно отвечать на все из них. Это никогда не должно разбиться. Пользователь всегда должен получить какое-то разумное сообщение о том, что пошло не так и как это исправить. Это не мусор на входе / вылет мусора, это мусор на входе / ошибка .
В то время как можно было бы отклонить получающиеся взрывы, потому что "никакой реальный пользователь не сделает это", это упускает смысл упражнения. Fuzzing - это дешевый способ устранить ваши предубеждения относительно возможных входных данных. Это дешевый способ бросить все странные вещи, которые пользователи попытаются сделать в вашей системе. Как инженер, ваша задача - убедиться, что ваша система выходит из строя.
Более того, нечеткий «ввод» касается не только пользователей. Это может быть результат запроса API к стороннему сервису, что если он начнет отправлять испорченные результаты? Как ваша система справляется с этим? Надлежащая система должна предупредить администратора, что компонент вышел из строя. Неправильная система тихо отклонит плохой запрос или, что еще хуже, примет его как хорошие данные.
Наконец, некоторые пользователи являются вредоносными. Если вы не проводите фазз-тестирование вашей системы, это сделает кто-то другой. Они будут проверять края вашей системы на наличие распространенных ошибок и пытаться использовать их в качестве дыр в безопасности. Нечеткое тестирование может в некоторой степени имитировать это, и вы можете устранить любые возможные дыры в безопасности, обнаруженные до того, как они станут проблемой.
источник
Если ваша цель - создать качественный продукт, протестируйте каждый возможный тип ввода, который физически сможет предоставить пользователь. В противном случае вы просто ждете того дня, когда кто-то представит этот тип ввода, который вы не считаете нужным для тестирования.
Во время большой демонстрации нового программного обеспечения для электронных аукционов в местном органе власти, где я работал, мой менеджер решил (по общему признанию, с некоторой шалостью), что он чувствует необходимость увидеть, что произошло, если он выставит на торги предложение с отрицательным значением. К моему искреннему удивлению, программное обеспечение аукциона позволило этой бессмысленной заявке и всему процессу аукциона приостановиться. Тип аукциона, который демонстрируется, никогда не должен позволять представлять отрицательные суммы.
Некоторые из большой группы сотрудников по закупкам и финансам были раздражены моим менеджером за то, что они представили бессмысленную оценку. Но другие, включая меня, были раздражены разработчиками программного обеспечения за то, что они не смогли протестировать и отклонить такой очевидный тип неверного ввода. Я могу только представить, насколько слабым должно быть программное обеспечение для отклонения других типов недопустимого ввода (попытки внедрения кода, экзотические символы, не представленные в таблице базы данных и т. Д.).
Если бы это было до меня, я бы вернул программное обеспечение и посчитал его непригодным для этой цели. Разница между слабым и сильным программным продуктом заключается в уровне тестирования, которому он был подвергнут.
источник
test every possible type of input that a user will be physically able to submit.
- Эта проблемная область по существу бесконечна, и вы тратите свое время, пытаясь все это проверить. Проверка на отрицательные входы - это единичная бифуркация; это не только разумно, но и ожидается от компетентных разработчиков. Вам не нужно проверять каждое отрицательное число, чтобы доказать, что такая проверка работает.Да. Это своего рода тест, но это не функциональный тест . Это то, что называется стресс-тестированием . Это акт оказания давления на систему, чтобы увидеть, сможет ли она справиться с этим.
Когда вы тестируете программное обеспечение для стресс- тестирования, вы пытаетесь определить границы ограничений программного обеспечения.
Тесты носят исчерпывающий характер. Где вам нужно определить пределы использования, точки останова, проверить все логические ветви или посмотреть, как частичные сбои влияют на всю систему.
Вы можете пройти все свои функциональные тесты, но все равно не пройти стресс- тестирование.
Да, это стандартная практика.
Тестирование программного обеспечения - это вопрос о предполагаемом поведении, и когда все тесты пройдены, это говорит о том, что программное обеспечение работает так, как задумано. Вот почему тесты создают хорошие предварительные условия для развертывания обновлений.
Стресс-тестирование не дает четких показателей прохождения или неудачи. Результаты более информативны. Он говорит вам, что ваша система может обрабатывать, и вы принимаете решения на основе этой информации.
Вы можете определить конкретные цели для стресс-тестирования, которые необходимо пройти, чтобы перейти к следующему этапу разработки. Они могут быть включены как часть вашего процесса обеспечения качества, но изменения в окружающей среде могут изменить результаты стресс-теста. Поэтому люди проводят стресс-тесты в разное время, чтобы увидеть, как система справляется с изменяющимися условиями.
Я имею в виду, что вы не можете просто проводить стресс-тестирование каждый раз, когда развертываете новую версию своего программного обеспечения, и предполагать, что это означает, что все пройдет стресс-тестирование позже.
источник