Как вы можете TDD для ошибки, которая может быть проверена только после того, как она была исправлена?

13

Вот один пример: мое веб-приложение содержит перетаскиваемые элементы. При перетаскивании элемента браузер создает «призрачное изображение». Я хочу удалить «призрачное изображение» при перетаскивании, и я пишу тест для этого поведения.

Моя проблема в том, что я изначально не представляю, как исправить эту ошибку, и единственный способ написать тест - это исправить его.

В простой функции, такой как let sum = (a, b) => a - b, вы можете написать тест на то, почему sum(1, 2)он не равен 3перед написанием любого кода.

В случае, который я описываю, я не могу проверить, потому что я не знаю, что такое проверка (я не знаю, каким должно быть утверждение).

Решение описанной проблемы:

let dataTransfer = e.dataTransfer
let canvas = document.createElement('canvas');
canvas.style.opacity = '0';
canvas.style.position = 'absolute';
canvas.style.top = '-1000px';
dataTransfer.effectAllowed = 'none';

document.body.appendChild(canvas);
dataTransfer.setDragImage(canvas, 0, 0);

Я не мог знать, что это было решением. Я не мог даже написать тест после нахождения решения в Интернете, потому что единственный способ узнать, действительно ли оно работает, было добавить этот код в мою кодовую базу и проверить в браузере, имеет ли он желаемый эффект. Тест должен был быть написан после кода, который идет вразрез с TDD.

Каким будет подход TDD к этой проблеме? Написание теста перед кодом обязательно или необязательно?

maximedupre
источник
2
Сделайте свое исследование тогда. Найти решение ... затем написать свой тест, исправить и рефакторинг. Тесты предназначены не только для проверки работоспособности вашего кода, но и для проверки вашего полного решения в будущем. Изначально вы создаете свой тест на провал, поэтому какое свойство вы будете тестировать? Это один из способов начать.
Хуан Карлос Эдуардо Ромайна Ас
@Kilian Foth: Я вижу твои благие намерения, меняя название вопроса, но твое редактирование лишает законной силы части моего ответа. Более того, ваше новое название имхо не вписывалось в тело вопроса. Поэтому я сделал откат, без обид.
Док Браун

Ответы:

26

Когда я вас правильно понял, вы даже не можете написать надежный автоматический тест для своего примера «призрачного изображения» после того, как найдете решение, поскольку единственный способ проверить правильность поведения - это посмотреть на экран и проверить, нет ли изображения-призрака больше Это создает впечатление, что ваш оригинальный заголовок задал неправильный вопрос. Настоящий вопрос должен быть

  • Как автоматически проверить определенное поведение графического интерфейса пользователя?

И ответ таков: по нескольким видам проблем с пользовательским интерфейсом вы этого не сделаете . Конечно, можно попытаться автоматизировать создание пользовательского интерфейса, показывающего проблему, и попытаться реализовать что-то вроде сравнения снимков экрана, но это часто подвержено ошибкам, хрупко и не рентабельно.

В частности, дизайн пользовательского интерфейса «тест-драйв» или улучшения пользовательского интерфейса с помощью автоматических тестов, написанных заранее, буквально невозможны. Вы «управляете» дизайном пользовательского интерфейса, делая улучшения, демонстрируете результат человеку (себе, некоторым тестировщикам или пользователю) и запрашиваете обратную связь.

Итак, примите тот факт, что TDD не является «серебряной пулей», и для некоторых проблем ручное тестирование все же имеет больше смысла, чем автоматическое тестирование. Если у вас есть систематический процесс тестирования, может быть, с некоторыми выделенными тестировщиками, лучшее, что вы можете сделать, это добавить кейс в их план тестирования.

Док Браун
источник
В общем, тестирование пользовательского интерфейса нетривиально; Вы можете закрепить, т.е. хешировать сгенерированное изображение, вы можете имитировать / автоматизировать, вы можете записывать макросы, вы можете использовать проприетарное решение, вы можете использовать ручное тестирование, это зависит от ситуации и от того, насколько необходимо автоматизированное тестирование пользовательского интерфейса для вашего проекта.
esoterik
1
@esoterik: да, и все эти автоматизированные методы подвержены ошибкам и хрупки, как я уже писал. Единственный нехрупкий подход, который я знаю, - это ручное тестирование.
Док Браун
3
Спасибо за ответ. Я думаю, что вы правы, я ошибочно надеюсь найти серебряную пулю в TDD. Кажется, не существует эффективного способа проверить то, что я хочу протестировать - сравнение скриншотов и все вышеперечисленное, похоже, не дают достаточного ROI. В частности, сравнение снимков экрана занимает много времени и, как вы сказали, подвержено ошибкам.
maximedupre
1
@maximedupre: нашел это объявление для инструмента, который пытается решить проблему, но, тем не менее, статья, похоже, согласна с моим ответом в целом.
Док Браун
5

Каким будет подход TDD к этой проблеме? Написание теста перед кодом обязательно или необязательно?

Одним из способов является применение аналога спайка решения .

Джеймс Шор описал это так:

Мы проводим небольшие отдельные эксперименты, когда нам нужно больше информации.

Основная идея заключается в том, что вы опускаете инструменты проектирования , пока выясняете, что происходит. Как только у вас есть ориентиры, вы снова берете инструменты проектирования.

Хитрость: вы возвращаете знания из своего исследования обратно в базу производственного кода, но вы не приносите код . Вместо этого вы воссоздаете его, используя ваши дисциплинированные приемы проектирования.

Лошади на курсы.

РЕДАКТИРОВАТЬ:

Как можно автоматизировать тест, если дефект виден только человеческим глазом?

Я хотел бы предложить несколько другое правописание: «Как вы можете автоматизировать тест, если автоматизация теста не является экономически эффективной?»

Ответ, конечно же, «вы не делаете». Вместо этого старайтесь разделить вашу реализацию на две части - большую часть, где тестирование является экономически эффективным, и меньшую часть, которую слишком просто разбить.

Существует два способа конструирования программного обеспечения: один из них - сделать его настолько простым, чтобы в нем явно не было недостатков - CAR Hoare

Поэтому при работе со сторонним кодом у нас будет очень тонкая оболочка кода, которая действует как прокси для сторонней библиотеки. В тесте мы заменяем эту оболочку на «двойник теста», который проверяет протокол , не беспокоясь о том, что он дает желаемый эффект.

Для тестирования интеграции наших кодов с реальным сторонним кодом мы полагаемся на другие методы (визуальная проверка, обращения в службу технической поддержки, оптимизм ....)

Может быть полезно сохранить некоторые демонстрационные артефакты, чтобы вы могли проверить, сохраняются ли ваши предположения при обновлении сторонней библиотеки.

VoiceOfUnreason
источник
Мне нравится то, что говорит Джеймс Шор. В настоящее время я следую за скринкастом www.letscodejavascript.com и многому учусь. Я прочитаю ссылки, на которые вы мне указали.
maximedupre
Вы правы, я читал больше о TDD и шипах. Вам действительно нужно знать, как выглядит код, который вы пытаетесь проверить, прежде чем пытаться его протестировать. TDD не может научить вас чему-то, чего вы еще не знаете, но потенциально он может показать вам кое-что, чему вы должны научиться, перефразируя Джеймса Шора. На этой ноте я хотел бы предложить дополнительный шаг в TDD: Spike, Test, Fail, Pass, Refactor.
maximedupre
0

С другой стороны, тестирование вокруг UI / GUI можно сделать несколько лучше в отношении приемочного тестирования (функциональные / бизнес-ориентированные тесты).

Я думаю, что для сети фреймворки, такие как Selen Webdriver, могут приблизиться к правильному тесту, но издержки для начала работы могут быть довольно значительными, и это сдвиг в потоке, наблюдаемом с TDD, в отношении только модульных тестов. ,

Часть, которая будет особенно полезна в вашей ситуации, называется объектной моделью страницы ( https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html ). Это обеспечивает явное отображение графического интерфейса во время выполнения на некоторый код, либо путем присвоения имен методам / событиям / членам класса.

Основными аргументами против этого могут быть накладные расходы, и что эти накладные расходы обычно можно увидеть в конце цикла разработки. Издержки заключаются в том, что тестам требуется некоторая оболочка, которая может создать дублирующую работу.

В дальнейшем это будет зависеть от затрат / выгод команды и бизнеса, поэтому это может быть полезной темой для обсуждения, чтобы определить ожидания и взгляды.

eparham7861
источник
Я на самом деле недавно пробовал e2e / функциональные тесты (с селеновым webdriver) в TDD, но издержки, как вы сказали, слишком велики. Вы не можете быть эффективным разработчиком и делать TDD с тестами e2e. Я использовал POM, но единственным преимуществом, которое он мне дал, была улучшенная архитектура в моей тестовой базе кода.
maximedupre
Да, я думаю, что более жизнеспособный вариант, который я видел в разных компаниях для разных команд, заключался бы в включении более ручного процесса SQA, когда команда / член команды назначается только для того, чтобы предварительно выполнять ручные тесты из пользовательского интерфейса. Тесты в основном имеют скриншоты и пошаговую документацию. По крайней мере, что-то подобное даст некоторое свидетельство тестирования приложения.
eparham7861
0

Как выглядит призрачное изображение? Если вы создали фиктивный пользовательский интерфейс одного известного цвета, куда вы поместили свой перетаскиваемый компонент? Будет ли присутствовать определенный цвет, если будет призрачное изображение.

Затем тест может проверить отсутствие цвета изображения-призрака.

Такой тест был бы разумным, долговечным и выполнимым.

Эсбен Сков Педерсен
источник
Выполнимо - да. Прочный - зависит. Простое изменение цвета / темы вашего пользовательского интерфейса может нарушить ваши тесты, но это не кажется мне слишком долговечным.
Шон Бертон,
1
Вы не будете тестировать весь ваш интерфейс. Вы бы создали фиктивный интерфейс для компонента drag-n-drop.
Эсбен Сков Педерсен
Я не уверен, как выполнить то, что вы предлагаете. Призрачное изображение в моем случае будет полупрозрачной копией перетаскиваемого элемента. Призрачное изображение всегда следует за курсором, пока происходит перетаскивание.
maximedupre
Да. Вы должны были бы автоматизировать перетаскивание. Это был бы не модульный тест, а тест e2e.
Эсбен Сков Педерсен