Как можно проверить взаимодействия JavaScript, такие как рисование мышью на холсте html5 - PullRequest
2 голосов
/ 20 марта 2012

Я знаком с тестированием состояний объектов, таких как rspec в ruby ​​на моделях rails.Например: этот объект должен соответствовать этому ожиданию, учитывая это предыдущее состояние и получение этого вызова.

Но что, если я захочу сделать TDD на плагине jquery для рисования линий на холсте html5?Как я могу проверить это?Учитывая, что пользователь нажал на холст и переместил указатель, на холсте должна быть нарисована линия.Не похоже, что я могу имитировать пользовательскую активность, используя жасмин, верно?Это что-то, что выходит за рамки TDD и может выполнять только ручное тестирование для?

Ответы [ 2 ]

4 голосов
/ 22 марта 2012

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

Я не очень знаком с холстом. Я бы сделал это одним из следующих способов:

1) Если вы хотите убедиться, что ваш код что-то делает с холстом, просто использовать шпионов прямо на нем. Шпионы - очень мощные инструменты, узнайте о них и используйте их. Например, если вы хотите убедиться, что путь к холсту обновлен, вы можете сделать

var spy = spyOn(canvas, 'moveTo').andCallFake(function (x, y) {
  expect(x).toEqual(10.0);
  expect(y).toEqual(20.0);
});

//Do something through your api that would call canvas.moveTo
...
expect(spy).toHaveBeenCalled();

Конечно, вы могли бы шпионить за любым другим методом canvas.

2) Если вам нужны тесты, которые выполняют много взаимодействий, и / или вы снова и снова пишете одних и тех же шпионов для разных тестов, возможно, вам лучше использовать фиктивный объект. Будьте осторожны: не переписывайте библиотеку, над которой вы издеваетесь! Сохраняйте это простым и высмеивайте только то, что вам нужно, добавляя по ходу дела. Кроме того, взгляните на доступные насмешливые библиотеки, которые могут помочь вам или дать вам идеи. Многие жасмины используют sinon . Лично я придерживаюсь голого жасмина и полагаюсь на свои собственные издевательства, когда они мне нужны.

Правильно, так что позвольте мне попытаться придумать что-нибудь;) Для холста я бы ожидал, что объект-насмешник скажет необходимые вам методы, beginPath, moveTo, stroke, что угодно ... Вы можете сделать так, чтобы вместо рисования на холсте они добавляли точки в массив, представляющий ваш путь. Тогда ваш тест станет набором взаимодействий с вашим кодом, и в конце вы сможете получить путь от макета и дать ожидаемые результаты.

1 голос
/ 21 марта 2012

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

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

var can = document.getElementById ('canvas1'); var ctx = can.getContext ('2d');

can.addEventListener('mousedown', function(e) {
    var mouse = getMouse(e, can);
    doMouseDown(ctx, mouse.x, mouse.y);
}, false);

can.addEventListener('mouseup', function(e) {
    var mouse = getMouse(e, can);
    doMouseUp(ctx, mouse.x, mouse.y);
}, false);


function doMouseDown(ctx, x, y) {
    ctx.beginPath();
    ctx.moveTo(x, y);
}

function doMouseUp(ctx, x, y) {
    ctx.lineTo(x, y);
    ctx.stroke();
}

Теперь, если вы хотите смоделировать пользователя, который кладет свою мышь куда-то вниз, то вам нужно написать следующее:

// simulate the mouse doing these actions!
doMouseDown(ctx, 50, 50);
doMouseUp(ctx, 200, 120);​

Достаточно просто!

Это не самый блестящий способ делать подобные вещи, но он дает вам идею. Я бы сделал своего рода объект / класс состояния для каждого холста, но это просто вопрос организации.

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

Вот полный рабочий пример для вас: http://jsfiddle.net/CU72J/

...