Подтвердить что ты не робот

Каковы стратегии тестирования модулей для D3JS?

Я совершенно новичок в D3JS и хотел бы понять стратегии тестирования для D3 JS.

Чтобы подробнее рассказать о вопросе - подумайте, что у меня есть простая страница, которая показывает линейный граф с использованием файла TSV.

Java Script Код:

function LineManager() {}
function LineProperties() { // Line Properties }
LineManager.prototype.draw = function(properties) { 
  // D3 code to draw a line with the given properties.
}

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

it("should throw an exception if line graph properties are not set.", function() {
        expect(lineManager.draw.bind(lineManager)).toThrow("Line Graph properties not set");
    });

it("It should have single line chart", function() {
    lineManager.draw(properties);
    expect(lineManager.countLines()).toEqual(1);
});

Я написал модульные тесты, чтобы убедиться, что TSV файл генерируется правильно. Но имеет ли смысл писать unit test, чтобы увидеть, правильно ли обрабатываются данные? Разве это не больше d3js unit test, а не unit test для моей функции?

Итак, мой вопрос: какие тесты следует рассматривать для диаграмм, генерируемых d3js?

4b9b3361

Ответ 1

Думаю, я получил ответ на свой вопрос. Попробуем объяснить это здесь.

Невозможно проверить правильность построения графика функцией JS, написанной с использованием D3JS. Для этого нам, возможно, придется использовать Phantom.js или аналогичную структуру, как упомянуто Крисофером. Я не беспокоился о том, что D3JS правильно рисует график, так как любые возможности D3JS и мой код могут с уверенностью предположить, что D3JS выполняет свою работу.

Мое беспокойство связано с тем, правильно ли переданы данные D3JS и согласно моим требованиям. Очень возможно удостовериться, что свойства графика установлены правильно, создавая объекты-шпионы. Я предоставляю образец unit test, охватывающий тестовые примеры для JS-кода, отображающего круг, используя D3JS.

CircleManager.js

function CircleManager() {};

CircleManager.prototype.draw = function(radius) {
    var svg = d3.select("body")
            .append("svg");

    svg.attr("width", 100)
            .attr("height", 100);    

    var circle = svg.append("circle");
    circle.style("stroke", "black")
        .style("fill", "white")
        .attr("r", radius)
        .attr("cx", 50)
        .attr("cy", 50);
};

CircleManagerSpec.js

describe("draw", function() {
    it("Constructs an svg", function() {
        var d3SpyObject = jasmine.createSpyObj(d3, ['append', 'attr']);

        // Returns d3SpyObject when d3.select method is called
        spyOn(d3, 'select').andReturn(d3SpyObject);

        var svgSpyObject = jasmine.createSpyObj('svg', ['append', 'attr', 'style']);

        // Returns svgSpyObject when d3.select.append is called.
        d3SpyObject.append.andReturn(svgSpyObject);


        d3SpyObject.attr.andCallFake(function(key, value) {
            return this;
        });

        svgSpyObject.append.andReturn(svgSpyObject);

        svgSpyObject.attr.andCallFake(function(key, value) {
            return this;
        });

        svgSpyObject.style.andCallFake(function(key, value) {
            return this;
        });

        var circleManager = new CircleManager();
        circleManager.draw(50);
        expect(d3.select).toHaveBeenCalledWith('body');
        expect(d3SpyObject.append).toHaveBeenCalledWith('svg');
        expect(svgSpyObject.attr).toHaveBeenCalledWith('r', 50);
        expect(svgSpyObject.attr).toHaveBeenCalledWith('width', 100);
        expect(svgSpyObject.attr).toHaveBeenCalledWith('height', 100);
        expect(svgSpyObject.style).toHaveBeenCalledWith('stroke', 'black');
        expect(svgSpyObject.style).toHaveBeenCalledWith('fill', 'white');
    });
});

Надеюсь, что это поможет.

Ответ 2

Стратегия тестирования

Стратегия, которую я использую для тестирования кода d3.js, заключается в создании вспомогательных функций для управления моими данными и настройками. Я тогда unit test эти функции. Поэтому для диаграмм я бы проверял каждую функциональность, связанную с данными, каждую функцию, чтобы установить ширину, легенды и т.д.

Что касается функций рисования, это может оказаться более сложным, но с такими фреймворками тестирования, как buster.js, их также может быть легко реализовать. Хорошим способом тестирования диаграммы будет подсчет количества баров/строк на странице, проверка печати легенд и т.д.

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


Тестирование Javascript

Отличная книга по тестированию javascript: Test Driven Javascript Development. Он содержит множество примеров и стратегий для проверки кода JavaScript. Большинство из них могут быть непосредственно применены к коду d3.js.


Инструменты

Недавно я искал решения для модульного тестирования кода d3.js, и в итоге я использовал следующие инструменты:

buster.js

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

phantom.js

phantom.js - это безгласный скрипт WebKit с API JavaScript.

Это означает, что он упрощает запуск автоматических тестов на javascript без необходимости использования таких браузеров, как хром, сафари и т.д.


EDIT: Я бы теперь использовал жасмин для модульного тестирования и селена (возможно, через сервис Saucelabs) для тестирования конца.

Ответ 3

Думаю, вам стоит подумать над этим: http://busypeoples.github.io/post/testing-d3-with-jasmine/

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

Нам явно не нужно проверять, правильно ли работает D3, или нет. Поэтому мы можем использовать D3 внутри нашего тестового кода. Но D3 создает SVG, и мы можем проверять такие вещи, как если бы у svg были элементы, где ожидалось. Опять же, он не собирается проверять, демонстрирует ли SVG и правильно ли отображается или нет. Мы собираемся проверить, есть ли у SVG элементы, которые ожидаются, и они установлены как ожидалось.

Например: Если это гистограмма, мы можем проверить количество баров. Как в примере в приведенной выше ссылке, это проверяет, что.

    // extend beforeEach to load the correct data...
beforeEach(function() {
    var testData =  [{ date: '2014-01', value: 100}, { date: '2014-02', value: 140}, {date: '2014-03', value: 215}];
    c = barChart();
    c.setData(testData);
    c.render();
});

describe('create bars' ,function() {
    it('should render the correct number of bars', function() {
        expect(getBars().length).toBe(3);
    });

    it('should render the bars with correct height', function() {
        expect(d3.select(getBars()[0]).attr('height')).toBeCloseTo(420);
    });

    it('should render the bars with correct x', function() {
        expect(d3.select(getBars()[0]).attr('x')).toBeCloseTo(9);
    });

    it('should render the bars with correct y', function() {
        expect(d3.select(getBars()[0]).attr('y')).toBeCloseTo(0);
    });
});

// added a simple helper method for finding the bars..
function getBars() {
    return d3.selectAll('rect.bar')[0];
}

Некоторые люди, вероятно, скажут, что мы будем использовать D3 внутри кода тестирования? Опять же, мы должны помнить, что цель тестового письма здесь заключается не в тестировании D3, а в нашей логике и SVG-коде, который компилируется в ответ на наш код.

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

Я думаю, что ясно, если нет, то проверьте эту ссылку: http://busypeoples.github.io/post/testing-d3-with-jasmine/

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