HTML Canvas Unit тестирование - PullRequest
       21

HTML Canvas Unit тестирование

30 голосов
/ 10 декабря 2010

Как я могу протестировать Javascript, который рисует на холсте HTML?Рисунок на холсте должен быть проверен.

Ответы [ 7 ]

16 голосов
/ 05 ноября 2011

Я написал пример для модульного тестирования canvas и других типов изображений y с помощью Jasmine и js-imagediff.

Жасминовые холст-тесты

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

8 голосов
/ 26 апреля 2011

Как обсуждено в комментариях к вопросу, важно проверить, что определенные функции были вызваны с подходящими параметрами. pcjuzer предложила использовать шаблон прокси. В следующем примере (код RightJS) показан один из способов сделать это:

var Context = new Class({
    initialize: function($canvasElem) {
        this._ctx = $canvasElem._.getContext('2d');

        this._calls = []; // names/args of recorded calls

        this._initMethods();
    },
    _initMethods: function() {
        // define methods to test here
        // no way to introspect so we have to do some extra work :(
        var methods = {
            fill: function() {
                this._ctx.fill();
            },
            lineTo: function(x, y) {
                this._ctx.lineTo(x, y);
            },
            moveTo: function(x, y) {
                this._ctx.moveTo(x, y);
            },
            stroke: function() {
                this._ctx.stroke();
            }
            // and so on
        };

        // attach methods to the class itself
        var scope = this;
        var addMethod = function(name, method) {
            scope[methodName] = function() {
                scope.record(name, arguments);

                method.apply(scope, arguments);
            };
        }

        for(var methodName in methods) {
            var method = methods[methodName];

            addMethod(methodName, method);
        }
    },
    assign: function(k, v) {
        this._ctx[k] = v;
    },
    record: function(methodName, args) {
        this._calls.push({name: methodName, args: args});
    },
    getCalls: function() {
        return this._calls;
    }
    // TODO: expand API as needed
});

// Usage
var ctx = new Context($('myCanvas'));

ctx.moveTo(34, 54);
ctx.lineTo(63, 12);

ctx.assign('strokeStyle', "#FF00FF");
ctx.stroke();

var calls = ctx.getCalls();

console.log(calls);

Функциональную демонстрацию можно найти здесь .

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

1 голос
/ 14 ноября 2018

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

Как писал Кристи в своем ответе, проблема в том, что обычные инструменты веб-тестирования, такие как Selenium, Protractor или Cucumber, не могут "видеть" то, что отображается на холсте.

Что мне помогло, так это использование визуального тестирования пользовательского интерфейса функций Kantu Selenium IDE (бесплатно, с открытым исходным кодом). Он использует поиск изображений внутри холста , чтобы «получить что-то полезное обратно». Кроме того, есть команды xclick и xtype (sendkey), которые позволяют автоматизировать тесты холста .

1 голос
/ 07 февраля 2017

Я делаю действительно простые полотна и проверяю их мокко.Я делаю это так же, как Юхо Вепсяляйнен, но моя выглядит немного проще.Я написал это в ec2015.

Класс CanvasMock:

import ContextMock from './ContextMock.js'

export default class {
  constructor (width, height)
  {
    this.mock = [];
    this.width = width;
    this.height = height;
    this.context = new ContextMock(this.mock);
  }

  getContext (string)
  {
    this.mock.push('[getContext ' + string + ']')
    return this.context
  }
}

Класс ContextMock:

export default class {
  constructor(mock)
  {
    this.mock = mock
  }

  beginPath()
  {
    this.mock.push('[beginPath]')
  }

  moveTo(x, y)
  {
    this.mock.push('[moveTo ' + x + ', ' + y + ']')
  }

  lineTo(x, y)
  {
    this.mock.push('[lineTo ' + x + ', ' + y + ']')
  }

  stroke()
  {
    this.mock.push('[stroke]')
  }
}

некоторые тесты mocha, которые оценивают функциональность самого макета:

describe('CanvasMock and ContextMock', ()=> {
    it('should be able to return width and height', ()=> {
      let canvas = new CanvasMock(500,600)
      assert.equal(canvas.width, 500)
      assert.equal(canvas.height, 600)
    })
    it('should be able to update mock for getContext', ()=> {
      let canvas = new CanvasMock(500,600)
      let ctx = canvas.getContext('2d')
      assert.equal(canvas.mock, '[getContext 2d]')
    })
})

Тест мокко, который оценивает функциональность функции, которая возвращает холст:

import Myfunction from 'MyFunction.js'

describe('MyFuntion', ()=> {
it('should be able to return correct canvas', ()=> {
  let testCanvas = new CanvasMock(500,600)
  let ctx = testCanvas.getContext('2d')
  ctx.beginPath()
  ctx.moveTo(0,0)
  ctx.lineTo(8,8)
  ctx.stroke()
  assert.deepEqual(MyFunction(new CanvasMock(500,600), 8, 8), canvas.mock, [ '[getContext 2d]', '[beginPath]', '[moveTo 0, 0]', [lineTo 8, 8]', '[stroke]' ])
})

, поэтому в этом примере myfunction принимает холст, который вы передали в качестве аргумента (Myfunction (* 1015)* new CanvasMock (500 600) , 8, 8)) и записывает на нем строку от 0,0 до того, что вы передаете в качестве аргументов (Myfunction (new CanvasMock (500 600), ** 8, 8 **)), а затем возвращает отредактированный холст.

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

читайте о насмешках здесь

0 голосов
/ 21 ноября 2016

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

Лучше перехватить вызовы, сделанные на объекте canvas, и исследовать их. Вот несколько вариантов:

  1. Создать объект-обертку, который записывает все вызовы. Юхо Вепсяляйнен опубликовал такой пример.
  2. Если возможно, используйте такую ​​библиотеку, как frabric.js, которая предлагает более высокий уровень абстракции для рисования. «Чертежи» - это объекты JS, которые можно проверять напрямую или преобразовывать в SVG, что проще для проверки и тестирования.
  3. Используйте Столовая для перехвата всех вызовов функций и изменений атрибутов объекта Canvas. Это похоже на вариант 1.
  4. Используйте столовую с rabbit , которая предлагает вам несколько пользовательских сопоставителей Jasmine для размера и выравнивания и функцию getBBox (), которая может использоваться для определения размера и положения материала, рисуемого на холсте .
0 голосов
/ 28 декабря 2013

Я недавно смотрел на тестирование холста, и теперь я подумал о странице, которая позволяет сравнивать холст с «известной хорошей» версией изображения того, как холст должен выглядеть. Это сделало бы визуальное сравнение быстрым и простым.

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

Не совсем (вообще) автоматизирован - но он облегчает сравнение вывода вашего кода.

Edit:

Теперь я сделал это:

Utility to test canvas output

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

0 голосов
/ 14 февраля 2011

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

Лучшее, что вы можете сделать со стандартным холстом, - это проанализировать данные о пикселях (из putImageData / getImageData. Как и то, что говорил бедра).

Теперь, я еще не пробовал, но это может быть больше, чем вам нужно. Торт это библиотека для холста. Это использует много putImageData / getImageData. Этот пример может помочь с тем, что вы пытаетесь сделать с помощью теста.

Надеюсь, это поможет ответить на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...