Что такое принцип ноль не ноль
// Основной класс для проверок: «Ноль / не ноль»
A) Ноль на входе — Число —> 5/0
B) Ноль на входе — Длина строки —> Ольга / 1 пробел, 2 пробела, пустое поле
— Авторизация —> Авторизован / Не авторизован
— Посещение —> Заходил на сайт / Ранее не заходил
— Аватар —> Загружал / Ещё не загружал
— Деньги снимал —> Да / Нет
D) Ноль на выходе
— После совершения покупки баланс уйдет в ноль.
— После обработки поле станет пустым.
— Поиск вернет ноль результатов (хотя на входе у нас непустая строка поиска).
— Отчет на указанную дату будет пустым (опять же, дата на входе была указана не-ноль).
Классы эквивалентности: будни Золушки 2015/07 okiseleva.blogspot.com
Класс эквивалентности «Ноль-не ноль» 2016/12 okiseleva.blogspot.com
Классы эквивалентности для имен 2019/10 okiseleva.blogspot.com
Заблуждения программистов об именах Habr-146901
Ивану кредит не давать! 2019/10 okiseleva.blogspot.com
Классы эквивалентности для строки, которая обозначает число software-testing.ru
Классы эквивалентности для населенных пунктов в адресах 2019/10 okiseleva.blogspot.com
c Несколько простых правил:
Если область определения параметра — диапазон, то имеет смысл выделение трех классов эквивалентности: слева от диапазона (невалидные значения), сам диапазон (валидные значения) и справа от диапазона (снова невалидные). При выделении классов нужно использовать включающие границы с целью однозначности и точности: одно и то же значение не может относиться к двум классам одновременно.
Если область определения — набор неупорядоченных данных, то всегда можно выделить как минимум два класса — валидные и невалидные значения. Полученное разбиение можно «дробить» дальше. Например, множество латинских букв можно разбить на два подмножества: латиница в верхнем и нижнем регистре соответственно.
Класс эквивалентности «Ноль-не ноль»
Именно в нуле любят собираться ошибки. На сайте вроде просто поле, а где-то внутри система делит на него при подсчете процента покупки. Подставил ноль — все сломалось. Профит! Баг! Или продуман только позитивный сценарий — всегда заказывают больше нуля книг / пицц / настолок. Ввел ноль, а код обработки значения не написан. Опять сломалось… Или оставил поле пустым, а система тебе БАЦ, и эксепшен…
Поэтому тестируй ноль! Где? Давайте посмотрим.
Поле ввода — цифры есть
Числовое поле
Тут все просто. Если видим числовое поле, пробуем ноль
Число книг: ноль / не ноль.
Кол-во пар обуви: ноль / не ноль.
Возраст пациента: ноль / не ноль.
Номер заказа: ноль / не ноль.
Выручка в рублях: ноль / не ноль.
Коэффициент похожести: ноль / не ноль.
Заказ книг на OZON. Количество товара — числовое поле
Это логично, такую проверку делают многие. Легко найти число в числовом поле!
Но что, если поле не числовое? Сразу затык.
Длина строки
Можно ли применить классы эквивалентности «ноль-не ноль» там, где числа исходно нет? Если мы вводим не числа, а буквы?
Тут нет чисел, только строковые поля
Конечно, можно! Кладем наше поле на числовую ось и получаем класс «длина строки». Та-а-а-ак, допустимое имя по ТЗ — от 3 до 6 символов. Окей, а как насчет нуля? Что будет, если оставить строку пустой? Так мы применяем класс «ноль-не ноль».
Длина имени: ноль / не ноль.
Длина эл почты: ноль / не ноль.
Длина пароля: ноль / не ноль.
Длина названия организации: ноль / не ноль.
Состояние объекта — цифр нет
Легко подставить ноль туда, где есть цифры. Несложно положить символьную строку на числовую ось и найти границы по длине строки. Что будет, если оставить строку пустой? А если заполнить? А если ввести только один символ (пограничное значение)?
Число книг: ноль / не ноль.
Символов в имени: ноль / не ноль.
Сложно применить класс «ноль / не ноль» там, где вроде бы нет цифр. И даже длины строки нет. В итоге тестировщик Вася ловит баг, но не может потом воспроизвести. Потому что не локализовал, не нашел точное условие → не записал его в шаги → задачу отложили → спустя месяц по шагам автора уже не воспроизводится, потому что его учетку удалили. А проблема была в ней, ведь Вася оплачивал продукты по PayPal до того, как возможность прикрыли. И забыли отмигрировать данные. На новой учетке даже возможности оплатить по PayPal нету (ноль) → баг не воспроизведется, ведь нам нужна учетка, где количество оплат по PayPal «не ноль».
И сидят Вася с Петей-разработчиком, копаются в логах, пытаются понять, как воспроизвести проблему. Или еще хуже — пожимают плечами, «А! Видимо, само починилось в рамках другой задачи» и закрывают баг как Cannot reproduce. И душа спокойна — теперь то работает! До тех пор, пока у реального пользователя баг не выстрелит. И тогда начнется паника, БЛОКЕР-приоритеты и все такое. А потом Петя поймет, в чем дело было, да даст Васе подзатыльник — сразу надо было про «ноль-не ноль» думать!
Учитесь видеть «ноль-не ноль» не только в числах и длине строк, но и в состояниях объекта:
Пользователь авторизован / не авторизован.
Заходил на сайт ранее / не заходил.
Заполнял профиль / не заполнял.
Аватарку загружал / не грузил.
Деньги снимал / не снимал.
Это самые крутые примеры класса, потому что о них не задумываются. Их пропускают. И именно поэтому их надо проверять. Как при поиске багов, так и при локализации конкретной ошибки: «Так-с, упало. А это всегда так или только при первом просмотре (раньше не смотрел — ноль, уже видел — не ноль)?».
Ноль на выходе
Не забывайте — ноль может быть не только на входе, но и на выходе!
— Ввести ноль в числовое поле,
— Оставить строку символов пустой.
— После совершения покупки баланс уйдет в ноль.
— После обработки поле станет пустым.
— Поиск вернет ноль результатов (хотя на входе у нас непустая строка поиска).
— Отчет на указанную дату будет пустым (опять же, дата на входе была указана не-ноль).
Пример
Посмотрим на примере Дадаты. Там куча нестандартных мест для проверки нашего класса «ноль-не ноль».
При регистрации у нас три унылых символьных поля, там все просто — поле заполнено или нет. Давайте найдем все классы с нулем для обработки файлов!
После авторизации появляется форма загрузки — https://dadata.ru/clean/.
1. Выбор файла (а вдруг пустой?)
Выбираем файл — Дадата отображает структуру. Если она вдруг неправильно определила тип, его всегда можно изменить в выпадающем списке:
2. Структура. Тут можно найти ноль?
Проверив структуру, переходим к предварительному результату. Если все ок, оплачиваем и получаем итоговый файл.
3. Предварительные результаты.
Они могут быть пусты, или баланс нулевой
— Файл может быть пустой: ноль строк, ноль колонок. Ок.
— Система распознает первую строку как шапку. А что, если у нас будет ноль «значимых» строк?
— Мы платим за обработку — а что, если у нас ноль рублей на счету? А что, если после обработки у нас станет ноль или даже меньше? Помним о том, что ноль может быть не только на входе, но и на выходе.
— А что, если у нас на выходе будет ноль данных? Если мы под видом ФИО пришлем фигню из серии “12345”? Да, колонки будут, но пустые же!
— А что, если на выходе вообще ничего? Присмотритесь к структуре, там же есть кнопка «Исключить столбец»! А что, если мы исключим все столбцы и получим на выходе ноль?
Столбцы можно исключать. И получить НОЛЬ на выходе!
Проверьте себя, найдите все нули в:
— форме обработки по одному человеку;
Чур, спойлеры в комментах не писать! =)
Просто в следующий раз, тестируя свою систему, вспомните о том, что ноль есть не только в числах и длинах полей. Ищите его там, где другие не ищут!Другие примеры:
— Период сегодня-вчера, если он длится 0 дней
— Применение класса «ноль-не ноль» при подключении к JMS
— Как пустой JSON вешает библиотечку Axis
0-1 принцип
Есть два способа проверить сеть из [math]n[/math] компараторов на то, что она сортирующая.
Первый способ
Первый, наивный способ — перебрать все перестановки из [math] n [/math] элементов, пропустить их через сеть и проверить их на то, что они отсортированы. Этот подход потребует [math] O(n! \cdot Comp(n)) [/math] действий, где [math] Comp(n) [/math] — количество компараторов в сети из [math]n[/math] элементов. Это количество можно оценить как [math] n \log^2n [/math] (Сеть Бетчера). Таким образом, получаем асимптотику [math] O(n!n \log^2n) [/math] , и при [math]n = 10[/math] проверить сеть очень проблематично.
Второй способ
Второй способ основывается на предположении, что если сеть сортирует все последовательности из нулей и единиц, то сеть является сортирующей. Если мы докажем это, то сможем проверять сеть за [math] O(2^n \cdot Comp(n)) [/math] , что намного быстрее.
Доказательство 0-1 принципа
Определение: |
Функция [math] f: A \rightarrow B [/math] называется монотонной (англ. monotonous), если [math] \forall a_1, a_2 \in A : a_1 \leqslant a_2 \Rightarrow f(a_1) \leqslant f(a_2) [/math] |
Пусть [math] f: A \rightarrow B [/math] — монотонная. Тогда [math] \forall a_1, a_2 \in A: f(\min(a_1, a_2)) = \min(f(a_1), f(a_2)) [/math] .
Не теряя общности, предположим что [math] a_1 \leqslant a_2 [/math] . Тогда [math] f(\min(a_1, a_2)) = f(a_1) [/math] . Также, по монотонности, [math] f(a_1) \leqslant f(a_2) [/math] . Тогда [math] \min(f(a_1), f(a_2)) = f(a_1) [/math] . То есть,
Определение: |
Рассмотрим отображение [math] f: A \rightarrow B [/math] и последовательность [math] a = (a_0, a_1, \dots, a_) [/math] . Определим [math] f(a) [/math] как последовательность [math] f(a_0), f(a_1), \dots , f(a_) [/math] , то есть [math] f(a_i) = f(a)_i [/math] |
Пусть [math] f: A \rightarrow B [/math] — монотонная, а [math] N [/math] — сеть компараторов. Тогда [math] N [/math] и [math] f [/math] коммутируют, то есть [math] N(f(a)) = f(N(a)) [/math] . Другими словами, неважно, применить сначала [math] f [/math] к [math] a [/math] и пропустить через сеть [math] N [/math] , или пропустить через сеть [math] N [/math] последовательность [math] a [/math] , а потом применить монотонную функцию [math] f [/math] .
Рассмотрим произвольный компаратор [math] [i: j] [/math] , сортирующий элементы [math] a_i [/math] и [math] a_j [/math] . Применим его к последовательности [math] f(a) [/math] и рассмотрим элемент с индексом [math] i [/math] .
Тогда [math] [i: j]f(a)_i =[/math]
- [math] [i: j](f(a_0), \dots, f(a_))_i [/math] (по введенному выше определению)
- [math] f([i: j](a))_i = f([i: j](a)_i) [/math] (по определению компаратора и по введенному выше определению)
- [math] \min(f(a_i), f(a_j)) = f(\min(a_i, a_j)) [/math] (по определению компаратора и по уже доказанной лемме).
Если сеть компараторов сортирует все последовательности из нулей и единиц, то она сортирующая
Рассмотрим сеть [math] N [/math] , сортирующую в возрастающем порядке: [math] a_0 \leqslant a_1 \leqslant \dots \leqslant a_ [/math] .
Предположим, что есть последовательность [math] a [/math] , которую сеть [math] N [/math] не сортирует. Тогда после пропуска [math] a [/math] через сеть [math] N [/math] , получим последовательность [math] b [/math] , в которой найдется индекс [math] i [/math] такой, что [math] b_i \gt b_ [/math] .
См. также
- Сеть Бетчера
- Сортирующие сети
Источники информации
- Bachelor-Studiengang Angewandte Informatik — Sorting networks
- Wikipedia — Sorting networks
- Дональд Кнут — Искусство программирования — Том 3 — Глава 5.3.4 — стр. 249
Тестирование методом эквивалентного разбиения.
Эквивалентное разбиение – это метод тестирования «черного ящика». Идея тестирования по методу разбиения классов эквивалентности состоит в том, чтобы исключить набор входных данных, которые заставляют систему вести себя одинаково и давать одинаковый результат при тестировании программы.
Эквивалентность. Разбиение на разделы является обычной методикой тестирования с использованием черного ящика и нацелено на сокращение числа избыточных тестовых сценариев, устраняя те, которые генерируют один и тот же результат, и не обязательно обнаруживают дефекты в функциональности программы.
Поскольку целью тестирования является обнаружение дефектов, то успешный тестовый сценарий – тот, который обнаруживает дефект.
Процесс тестирования по методу эквивалентного разбиения включает в себя идентификацию набора данных как условий ввода, которые дают одинаковый результат при выполнении программы и классифицируют их как набор эквивалентных данных (поскольку они заставляют программу вести себя одинаково и генерировать тот же результат ) и происходит разбиение их на группы из другого эквивалентного набора данных.
Наши курсы Тестирования ПО в Минске тщательно разбирают этот вопрос, поэтому рекомендуем записаться к нам прямо сейчас!
Рассмотрим пример ниже:
Можно ожидать, что приложение, принимающее целочисленные значения (целочисленные числа) от -10,000 до +10,000, сможет обрабатывать отрицательные целые числа, ноль и положительные целые числа. Таким образом, набор входных значений можно разделить на три раздела:
От -10 000 до -1, 0 и от 1 до 10000
Более того, ожидается, что система будет вести себя одинаково для значений внутри каждого раздела. То есть способ, которым система обрабатывает -6391, будет такой же, как -9. Аналогично, положительные целые числа 5 и 3567 будут обрабатываться системой одинаково. В этом конкретном примере значение 0 является разделом с одним значением. Обычно хорошей практикой является специальный сценарий с нулевым числом.
Важно отметить, что эта методика применима не только к цифрам. Этот метод может применяться к любому набору данных, который можно рассматривать как эквивалент. Например. Приложение, которое читает изображения только из трех типов: .jpeg, .gif и .png, тогда можно идентифицировать три набора допустимых эквивалентных классов.
Изображение с расширением .jpeg
Изображение с расширением .gif
Изображение с расширением .png.
Теперь, открыв файл .jpeg, который является образом луны, ПО будет вести себя так же, как файл с изображением собаки. Поэтому, открывая только один файл типа .jpeg, хватит одного тестового сценария. Предполагается, что система будет вести себя одинаково для всех jpeg-файлов.
Тот же сценарий применяется к файлам с файлами .gif и .png. Аналогично, если приложение не может открывать файлы, отличные от разрешенных и допустимых типов, то при попытке открыть текстовый документ результат будет таким же, как при попытке открыть таблицу Excel или текстовый файл. (Ожидается, что приложение было хорошо разработано, чтобы справиться с другими типами файлов и генерирует соответствующее сообщение при попытке открыть неприемлемые типы файлов).
Они будут классифицированы как набор недействительных эквивалентных данных. Пытаться открыть приложение с недопустимыми или недействительными типами файлов – пример отрицательного тестирования, что полезно в сочетании с тестированием по методу эквивалентного разбиения, который разбивает набор эквивалентных допустимых и достоверных данных.
Запишитесь на наши курсы Тестирования ПО в Минске прямо сейчас или закажите звонок с бесплатной консультацией!
Запишитесь прямо сейчас или закажите звонок с бесплатной консультацией!