Приспособления и Селен и направляющие (о, мой?)

Я разбил это на два этапа: 1. сгенерировать древовидную структуру из входных данных, чтобы позволить подсчет числа строк; 2. Рисование строк и столбцов таблицы.

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

Я также добавил динамический заголовок таблицы. Если вы добавите еще один столбец в структуру данных, заголовки таблицы HTML также будут обновлены. Например, можно использовать этот же код для добавления четвертого уровня, например, "LEVEL_4": "LEVEL 1.2.2.1" в один или несколько рядов.

var data = [
    {
        "LEVEL_1": "LEVEL 1",
        "LEVEL_2": "LEVEL 1.1",
        "LEVEL_3": "LEVEL 1.1.1"
    },
    {
        "LEVEL_1": "LEVEL 1",
        "LEVEL_2": "LEVEL 1.2",
        "LEVEL_3": "LEVEL 1.2.1"
    },
    {
        "LEVEL_1": "LEVEL 1",
        "LEVEL_2": "LEVEL 1.2",
        "LEVEL_3": "LEVEL 1.2.2"
    },
    {
        "LEVEL_1": "LEVEL 2",
        "LEVEL_2": "LEVEL 2.1",
        "LEVEL_3": "LEVEL 2.1.1"
    },
    {
        "LEVEL_1": "LEVEL 2",
        "LEVEL_2": "LEVEL 2.1",
        "LEVEL_3": "LEVEL 2.1.2"
    },
    {
        "LEVEL_1": "LEVEL 2",
        "LEVEL_2": "LEVEL 2.2",
        "LEVEL_3": "LEVEL 2.2.1"
    },
    {
        "LEVEL_1": "LEVEL 2",
        "LEVEL_2": "LEVEL 2.2",
        "LEVEL_3": "LEVEL 2.2.2"
    }
];

/**
 * Generate rows and columns for the table using the JSON data.
 *
 * @param {Object} data
 * @param {HTMLTableSectionElement} tableBody
 * @param {HTMLTableSectionElement} tableHead
 */
function setTableContent(data, tableBody, tableHead) {
    /* The rowspan is stored here depending on the label of each column */
    var columnRowspans = {};

    var columnHeadings = {};

    /**
     * Translate the data into a tree-like structure
     *
     * @param {JSON} data
     * @return {Array}
     */
    function translateData(data) {
        var rows = [];
        /* Iterate over each row in the dataset */
        data.forEach(function (row) {
            var columns = [],
                label;
            /* Find the individual columns */
            for (var key in row) {
                /* Store the columns header */
                columnHeadings[key] = true;

                label = row[key];
                /* Skip those columns that were already added */
                if (columnRowspans[label]) {
                    columnRowspans[label]++;
                    continue;
                }
                columns.push(label);
                columnRowspans[label] = 1;
            }
            rows.push(columns);
        });
        return rows;
    }

    /* Template string used for a single field in the table */
    var cellTemplate = '<td rowspan="{rowspan}">{content}</td>';

    /* Output */
    var html = '';
    translateData(data).forEach(function (row, index) {
        html += '<tr>';
        row.forEach(function (columnLabel) {
            /* Use the stored rowspans here to generate columns */
            html += cellTemplate
                .replace('{rowspan}', columnRowspans[columnLabel])
                .replace('{content}', columnLabel);
        });
        html += '</tr>';
    });

    if (tableBody instanceof HTMLTableSectionElement) {
        tableBody.innerHTML = html;
    }

    if (tableHead instanceof HTMLTableSectionElement) {
        var thead = '<tr>';
        Object.keys(columnHeadings).forEach(function (heading) {
            thead += '<th>' + heading.replace('_', ' ') + '</th>';
        });
        thead += '</tr>';
        tableHead.innerHTML = thead;
    }
}

setTableContent(data, document.querySelector('#user tbody'), document.querySelector('#user thead'));
 table { 
      border-collapse: collapse;
    }

    td {
      padding: 20px; 
      border: 1px solid black; 
      text-align: center;
    }

    th {
      padding: 20px; 
      border: 1px solid black; 
      text-align: center;
    }
<table id="user">
    <thead>
    </thead>
    <tbody> 
    </tbody>
</table>

8
задан Sarah Mei 13 March 2009 в 22:04
поделиться

3 ответа

Если Вы можете, самая лучшая вещь сделать, имеют систему, в которой каждый тест Селена получает свое собственное состояние данных (т.е.: Таблицы базы данных, отброшенные и воссозданные, загрузите данные, повторно вставленные, и очищенные кэши). Это легче сказать чем сделать и обычно только возможно если проект, запланированный его от запуска.

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

Худший случай, IMO, должен использовать статический DB, в котором каждый тестовый прогон видоизменяет дату. Это почти всегда приводит к проблемам и обычно является "запахом проекта". Ключ к выполнению его "правильный путь" (снова, IMO) состоит в том, чтобы быть бдителен в отношении любого изменения состояния/схемы и получить его как часть автоматизированного теста/процесса сборки.

Направляющие уже делают хорошее задание с этим с Миграциями, поэтому используйте в своих интересах их! Не зная Вашей ситуации, я обычно подвергал бы сомнению потребность запустить тесты Селена против снимка полного DB. Большая часть DBS может (или если) быть дистиллированной вниз меньше чем к 1 МБ для автоматизированного тестирования, делая автоматизированные миграции схемы, и данные сбрасывают намного более эффективный.

Единственное время я видел "допустимые" основания крупного DBS для тестов Селена, - когда сам DB содержит большие блоки "логических данных", в которых данные влияют на поток приложения (думайте: управляемый данными UI).

4
ответ дан 5 December 2019 в 21:22
поделиться

Я думаю, что Вы задаете два вопроса здесь, которые переплетены поэтому, если я должен сломать его:

  • Вы хотите получить данные тестирования в и из Вашего DB быстро, и приспособления не делают его для Вас.
  • Вы были записаны изменением схемы, и Вы хотите удостовериться, что независимо от того, что Вы делаете, не требует восьми повторений тематическая "игра с данными тестирования... все еще" :)

У Вас есть несколько альтернатив здесь, которые я долго обсудил ниже. Поскольку Вы упомянули Oracle, я использую технологии Oracle здесь, но то же самое верно для других платформ DB (например, Postgresql):

  1. Обстреляйте tesks, которые называют МН сценарии / сценарии SQL для генерации данных, противной ужасной злой идеи, не делают этого, если нет никакой другой опции. Я сделал это на одном проекте, который должен был загрузиться в миллиардах строк для некоторых тестов архитектуры инфраструктуры. Я все еще дуюсь об этом.
  2. Получите свой DB в формат дампа. Поскольку быстрые разгрузки двоичных данных проверяют утилиты объекта преобразования данных и exp/imp. Это позволит Вам быструю установку и разрушение Вашего DB. Конечно, на проекте направляющих я продолжил работать, мы привыкли задачи граблей для exp/imp база данных, которая имела вокруг записей 300k менее чем за минуту. Также проверьте SQLLoader, который является логической утилитой дампа, как его логическое ее медленнее и требует, чтобы у Вас были сценарии управления, чтобы помочь SQLLoader понять дампы. Однако преимущество логического дампа - то, что можно запустить скрипты преобразования по ним для массирования данных в последний формат. Печально, хотя точно так же, как приспособления все эти инструменты довольно чувствительны для изменения в схеме.
  3. Используйте плагин, такой как Машинист или Девочка Фабрики для создания поколения данных более хорошим. Вы все еще подвергаетесь штрафу использования ActiveRecord для установки DB, но эти поддельные объектные генераторы помогут Вам остаться близко к Вам миграции и являются намного меньшим количеством стычки для поддержания, чем приспособления.
  4. Объединение приближается 2 и 3. Что происходит, вот то, что Вы делаете некоторые данные тестирования с, заявляют Machinst. Вы экспортируете те данные тестирования в дамп и затем перезагружаете дамп во время каждого тестового прогона. Когда изменения схемы обновляют конфигурацию Машиниста и реэкспорт.

Надежда, которая помогает.

2
ответ дан 5 December 2019 в 21:22
поделиться

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

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

Посмотрите, например, задачи фиксации граблей Paul Gross на GitHub.

1
ответ дан 5 December 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: