Как обсуждалось в других тестовых запахах , таких как « След по конкурентным вычислениям» и « Вчера» , очень легко создавать неясные утверждения, которые либо ненадежны, либо не доказывают огромную сумму.
Хотя часто есть веские «плохие причины», объясняющие, почему мы не можем написать простые утверждения, признать, когда вы их не пишете, и сделать все возможное, чтобы вернуться к норме , это очень хорошая идея.
Давайте посмотрим на тест на вымышленном языке:
01
02
03
04
05
06
07
08
09
10
11
12
|
// Note - this is is no specific language test( 'adding user to database results in new user' , { user = createUser( 'John' , 'Smith' ) id = system.addUser(user) readUser = system.retrieveUser(id) assert (user.firstName).is( 'John' ) assert (user.lastName).is( 'Smith' ) }); |
Выше есть много свойств простого теста:
- Тестовые данные, которые мы используем «Джон» и «Смит» , просты и находятся прямо перед нами.
- Тестируемая система как API, который пригоден для тестирования
- Мы утверждаем с точными дискретными значениями, которые мы могли предсказать перед тестом
- Любые автоматически сгенерированные вещи, такие как id и, возможно, userCreationDate (не показаны), не влияют на наш тест
Но что насчет…?
В приведенном выше примере есть подсказка, что, возможно, пользователям предоставляется идентификатор, а также метка времени создания.
Может возникнуть соблазн попытаться написать утверждение вроде этого:
1
2
3
|
readUser = system.retrieveUser(id) assert (user).is(expectedUser) |
Там, где ожидается, что пользователь как-то настроен так, чтобы он содержал точное совпадение с пользователем, которое сгенерирует система.
Общий совет — если в тесте, называемом ожидаемым, есть построенный объект, существует высокий риск испытания по конкурентному расчету .
Чтобы получить возможность предсказывать сгенерированные системой вещи, нам нужно подключить к системе собственный генератор ключей и контрольные часы и т.д. Это может быть ценно, или это может быть куча тестового мусора.
Давайте нечеткий матч
Альтернатива для всего соответствия объекта — создать что-то вроде этого:
1
2
3
4
5
6
7
8
9
|
// still a fictional language readUser = system.retrieveUser(id) assert (user).matches([ { obj.firstName == 'John' }, { obj.lastName == 'Smith' }, { obj.id instanceof UUID }, { obj.creationDate - now() < inSeconds( 5 ) } ]) |
В этом составленном тесте есть несколько конкретных утверждений, а затем еще несколько нечетких утверждений.
Нечеткое сопоставление является громоздким
Вышеупомянутое решение показывает, как вы можете сделать относительно значимые утверждения о типе объекта, приблизительном значении объекта, возможно, вы могли бы даже сделать регулярное выражение для содержимого полей … оно позволяет вам утверждать значение, которое вы не можете предсказать …
Но…
Причина, по которой вышеприведенное утверждение получило большое распространение, заключается в том, что мы выполняли полное сопоставление объектов с чем-то, что не может быть полностью сопоставлено.
Это может быть лучший доступный вариант.
альтернативы
- Делайте нечеткие совпадения в отдельных тестах, по одному полю за раз — избегайте нечеткого совпадения всего объекта
- Отфильтруйте поля, которые не могут быть сопоставлены при сравнении данных — либо путем пропуска, либо путем копирования из фактического в ожидаемое, либо по правилам исключения в сравнении
- Настройте генераторы для получения предсказуемых значений.
- Напишите тесты более низкого уровня, которые могут предсказать значения, чтобы вам не пришлось полагаться на нечеткое сопоставление на более высоком уровне
Вывод
Нечеткое совпадение в наших утверждениях является хорошим трюком, чтобы уметь тянуть, но это должно быть последним средством, когда нет ничего проще.
Утверждение целых полезных нагрузок обычно заставляет нас сталкиваться с нечеткими проблемами соответствия.
Более точное сопоставление полей нижнего уровня может устранить необходимость нечеткости.
Смотрите оригинальную статью здесь: Нечеткие утверждения Мнения, высказанные участниками Java Code Geeks, являются их собственными. |