Автоматические тесты при помощи chai и mocha
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/testing-mocha.
В этой главе мы разберём основы автоматического тестирования. Оно будет применяться далее в задачах, и вообще, входит в «образовательный минимум» программиста.
Зачем нужны тесты?
При написании функции мы обычно представляем, что она должна делать, какое значение на каких аргументах выдавать.
В процессе разработки мы время от времени проверяем, правильно ли работает функция. Самый простой способ проверить – это запустить её, например в консоли, и посмотреть результат.
Если что-то не так, поправить, опять запустить – посмотреть результат… И так «до победного конца».
Но такие ручные запуски – очень несовершенное средство проверки.
Когда проверяешь работу кода вручную – легко его «недотестировать».
Например, пишем функцию f . Написали, тестируем с разными аргументами. Вызов функции f(a) работает, а вот f(b) не работает. Поправили код – стало работать f(b) , вроде закончили. Но при этом забыли заново протестировать f(a) – упс, вот и возможная ошибка в коде.
Автоматизированное тестирование – это когда тесты написаны отдельно от кода, и можно в любой момент запустить их и проверить все важные случаи использования.
BDD – поведенческие тесты кода
Мы рассмотрим методику тестирования, которая входит в BDD – Behavior Driven Development. Подход BDD давно и с успехом используется во многих проектах.
BDD – это не просто тесты. Это гораздо больше.
Тесты BDD – это три в одном: И тесты, И документация, И примеры использования.
Впрочем, хватит слов. Рассмотрим примеры.
Разработка pow: спецификация
Допустим, мы хотим разработать функцию pow(x, n) , которая возводит x в целую степень n , для простоты n≥0 .
Ещё до разработки мы можем представить себе, что эта функция будет делать, и описать это по методике BDD.
Это описание называется спецификация (или, как говорят в обиходе, «спека») и выглядит так:
У спецификации есть три основных строительных блока, которые вы видите в примере выше:
Задаёт, что именно мы описываем, используется для группировки «рабочих лошадок» – блоков it . В данном случае мы описываем функцию pow .
В названии блока it человеческим языком описывается, что должна делать функция, далее следует тест, который проверяет это.
Код внутри it , если реализация верна, должен выполняться без ошибок.
Различные функции вида assert.* используются, чтобы проверить, делает ли pow то, что задумано. Пока что нас интересует только одна из них – assert.equal , она сравнивает свой первый аргумент со вторым и выдаёт ошибку в случае, когда они не равны. В данном случае она проверяет, что результат pow(2, 3) равен 8 .
Есть и другие виды сравнений и проверок, которые мы увидим далее.
Поток разработки
Как правило, поток разработки таков:
- Пишется спецификация, которая описывает самую базовую функциональность.
- Делается начальная реализация.
- Для проверки соответствия спецификации мы задействуем фреймворк (в нашем случае Mocha). Фреймворк запускает все тесты it и выводит ошибки, если они возникнут. При ошибках вносятся исправления.
- Спецификация расширяется, в неё добавляются возможности, которые пока, возможно, не поддерживаются реализацией.
- Идём на пункт 2, делаем реализацию. И так «до победного конца».
Разработка ведётся итеративно: один проход за другим, пока спецификация и реализация не будут завершены.
В нашем случае первый шаг уже завершён, начальная спецификация готова, хорошо бы приступить к реализации. Но перед этим проведём «нулевой» запуск спецификации, просто чтобы увидеть, что уже в таком виде, даже без реализации – тесты работают.
Пример в действии
Для запуска тестов нужны соответствующие JavaScript-библиотеки.
Мы будем использовать:
-
– эта библиотека содержит общие функции для тестирования, включая describe и it . – библиотека поддерживает разнообразные функции для проверок. Есть разные «стили» проверки результатов, с которыми мы познакомимся позже, на текущий момент мы будем использовать лишь assert.equal . – для эмуляции и хитрой подмены функций «заглушками», понадобится позднее.
Эти библиотеки позволяют тестировать JS не только в браузере, но и на сервере Node.JS. Здесь мы рассмотрим браузерный вариант, серверный использует те же функции.
Пример HTML-страницы для тестов:
Эту страницу можно условно разделить на четыре части:
- Блок <head> – в нём мы подключаем библиотеки и стили для тестирования, нашего кода там нет.
- Блок <script> с реализацией спецификации, в нашем случае – с кодом для pow .
- Далее подключаются тесты, файл test.js содержит describe("pow", . ) , который был описан выше. Методы describe и it принадлежат библиотеке Mocha, так что важно, что она была подключена выше.
- Элемент <div > будет использоваться библиотекой Mocha для вывода результатов. Запуск тестов инициируется командой mocha.run() .
Пока что тесты не проходят, но это логично – вместо функции стоит «заглушка», пустой код.
Пока что у нас одна функция и одна спецификация, но на будущее заметим, что если различных функций и тестов много – это не проблема, можно их все подключить на одной странице. Конфликта не будет, так как каждой части кода соответствует свой блок describe("что тестируем". ) . Сами же тесты обычно пишутся так, чтобы не влиять друг на друга, не делать лишних глобальных переменных.
Начальная реализация
Пока что, как видно, тесты не проходят, ошибка сразу же. Давайте сделаем минимальную реализацию pow , которая бы работала нормально:
О, вот теперь работает:
Исправление спецификации
Функция, конечно, ещё не готова, но тесты проходят. Это ненадолго 🙂
Здесь мы видим ситуацию, которая (и не обязательно при ленивом программисте!) бывает на практике – да, есть тесты, они проходят, но функция (увы!) работает неправильно.
С точки зрения BDD, ошибка при проходящих тестах – вина спецификации.
В первую очередь не реализация исправляется, а уточняется спецификация, пишется падающий тест.
Сейчас мы расширим спецификацию, добавив проверку на pow(3, 4) = 81 .
Здесь есть два варианта организации кода:
Первый вариант – добавить assert в тот же it :
Второй вариант – сделать два теста:
Их принципиальное различие в том, что если assert обнаруживает ошибку, то он тут же прекращает выполнение блока it . Поэтому в первом варианте, если вдруг первый assert «провалился», то про результат второго мы никогда не узнаем.
Таким образом, разделить эти тесты может быть полезно, чтобы мы получили больше информации о происходящем.
Кроме того, есть ещё одно правило, которое желательно соблюдать.
Один тест тестирует ровно одну вещь.
Если мы явно видим, что тест включает в себя совершенно независимые проверки – лучше разбить его на два более простых и наглядных.
По этим причинам второй вариант здесь предпочтительнее.
Как и следовало ожидать, второй тест не проходит. Ещё бы, ведь функция всё время возвращает 8 .
Уточнение реализации
Придётся написать нечто более реальное, чтобы тесты проходили:
Чтобы быть уверенными, что функция работает верно, желательно протестировать её на большем количестве значений. Вместо того, чтобы писать блоки it вручную, мы можем сгенерировать тесты в цикле for :
Вложенный describe
Функция makeTest и цикл for , очевидно, нужны друг другу, но не нужны для других тестов, которые мы добавим в дальнейшем. Они образуют единую группу, задача которой – проверить возведение в n -ю степень.
Будет правильно выделить их, при помощи вложенного блока describe :
Вложенный describe объявит новую «подгруппу» тестов, блоки it которой запускаются так же, как и обычно, но выводятся с подзаголовком, вот так:
В будущем мы сможем добавить другие тесты it и блоки describe со своими вспомогательными функциями.
В каждом блоке describe можно также задать функции before/after , которые будут выполнены до/после запуска тестов, а также beforeEach/afterEach , которые выполняются до/после каждого it .
Последовательность будет такой:
Как правило, beforeEach/afterEach ( before/after ) используют, если необходимо произвести инициализацию, обнулить счётчики или сделать что-то ещё в таком духе между тестами (или их группами).
Расширение спецификации
Базовая функциональность pow описана и реализована, первая итерация разработки завершена. Теперь расширим и уточним её.
Как говорилось ранее, функция pow(x, n) предназначена для работы с целыми неотрицательными n .
В JavaScript для ошибки вычислений служит специальное значение NaN , которое функция будет возвращать при некорректных n .
Добавим это поведение в спецификацию:
Результат с новыми тестами:
Конечно, новые тесты не проходят, так как наша реализация ещё не поддерживает их. Так и задумано: сначала написали заведомо не работающие тесты, а затем пишем реализацию под них.
Другие assert
Обратим внимание, в спецификации выше использована проверка не assert.equal , как раньше, а assert(выражение) . Такая проверка выдаёт ошибку, если значение выражения при приведении к логическому типу не true .
Она потребовалась, потому что сравнивать с NaN обычным способом нельзя: NaN не равно никакому значению, даже самому себе, поэтому assert.equal(NaN, x) не подойдёт.
Кстати, мы и ранее могли бы использовать assert(value1 == value2) вместо assert.equal(value1, value2) . Оба этих assert проверяют одно и тоже.
Однако, между этими вызовами есть отличие в деталях сообщения об ошибке.
При «упавшем» assert в примере выше мы видим "Unspecified AssertionError" , то есть просто «что-то пошло не так», а при assert.equal(value1, value2) будут дополнительные подробности: expected 8 to equal 81 .
Поэтому рекомендуется использовать именно ту проверку, которая максимально соответствует задаче.
Вот самые востребованные assert -проверки, встроенные в Chai:
- assert(value) – проверяет что value является true в логическом контексте.
- assert.equal(value1, value2) – проверяет равенство value1 == value2 .
- assert.strictEqual(value1, value2) – проверяет строгое равенство value1 === value2 .
- assert.notEqual , assert.notStrictEqual – проверки, обратные двум предыдущим.
- assert.isTrue(value) – проверяет, что value === true
- assert.isFalse(value) – проверяет, что value === false
- …более полный список – в документации
В нашем случае хорошо бы использовать проверку assert.isNaN , и такой метод существует, но сейчас мы рассматриваем самый общий метод assert(. ) . В этом случае для того, чтобы сделать сообщение об ошибке понятнее, желательно добавить к assert описание.
Все вызовы assert позволяют дополнительным последним аргументом указать строку с описанием ошибки, которое выводится, если assert не проходит.
Добавим описание ошибки в конец наших assert’ов :
Теперь результат теста гораздо яснее говорит о том, что не так:
В коде тестов выше можно было бы добавить описание и к assert.equal , указав в конце: assert.equal(value1, value2, "описание") , но с равенством обычно и так всё понятно, поэтому мы так делать не будем.
Итого
Итак, разработка завершена, мы получили полноценную спецификацию и код, который её реализует.
Задачи выше позволяют дополнить её, и в результате может получиться что-то в таком духе:
Эту спецификацию можно использовать как:
- Тесты, которые гарантируют правильность работы кода.
- Документацию по функции, что она конкретно делает.
- Примеры использования функции, которые демонстрируют её работу внутри it .
Имея спецификацию, мы можем улучшать, менять, переписывать функцию и легко контролировать её работу, просматривая тесты.
Особенно важно это в больших проектах.
Бывает так, что изменение в одной части кода может повлечь за собой «падение» другой части, которая её использует. Так как всё-всё в большом проекте руками не перепроверишь, то такие ошибки имеют большой шанс остаться в продукте и вылезти позже, когда проект увидит посетитель или заказчик.
Чтобы избежать таких проблем, бывает, что вообще стараются не трогать код, от которого много что зависит, даже если его ну очень нужно переписать. Жизнь пробивается тонкими росточками там, где должна цвести и пахнуть новая функциональность.
Код, покрытый автотестами, являет собой полную противоположность этому!
Даже если какое-то изменение потенциально может порушить всё – его совершенно не страшно сделать. Ведь есть масса тестов, которые быстро и в автоматическом режиме проверят работу кода. И если что-то падает, то это можно будет легко локализовать и поправить.
Кроме того, код, покрытый тестами, имеет лучшую архитектуру.
Конечно, это естественное следствие того, что его легче менять и улучшать. Но не только.
Чтобы написать тесты, нужно разбить код на функции так, чтобы для каждой функции было чётко понятно, что она получает на вход, что делает с этим и что возвращает. Это означает ясную и понятную структуру с самого начала.
Конечно, в реальной жизни всё не так просто. Зачастую написать тест сложно. Или сложно поддерживать тесты, поскольку код активно меняется. Сами тесты тоже пишутся по-разному, при помощи разных инструментов.
Что дальше?
В дальнейшем условия ряда задач будут уже содержать в себе тесты. На них вы познакомитесь с дополнительными примерами.
Как правило, они будут вполне понятны, даже если немного выходят за пределы этой главы.
Создание теста для сайта на JavaScript

На этом уроке создадим тест с вопросами и полями для ввода ответов для дальнейшего размещения на сайте. Вопросы и ответы теста хранятся в последовательно идущих объектах, их которых состоит массив questions. В каждом объекте есть ключи (text, right) и их значения (вопрос, ответ). Вариант хранения вопроса и ответа в одном массиве очень удобен, особенно, если наверняка потребуется добавить или изменить эти данные.
let questions = [
<
text: 'Сокращенное название таблицы стилей?', // вопрос
right: 'CSS', // правильный ответ
>,
<
text: 'Кто верстает сайты?',
right: 'верстальщик',
>,
<
text: 'Самый популярный CSS-фреймворк?',
right: 'Bootstrap',
>,
];
JavaScript на основе массива questions налету создаст структуру HTML разметки. Для каждого объекта массива создается тег div, внутри которого будет параграф p, поле для ввода (input) и дата-атрибут с правильным ответом. То есть этих тегов не будет в HTML разметке, каждый раз они будут сгенерированы скриптом. У такого подхода есть преимущество — лучшая читаемость кода. Ведь вопросов может быть много, что размножит разметку.
<div>
<p>Сокращенное название таблицы стилей?</p>
<input data-right=»CSS»>
</div>
<div>
<p>Кто верстает сайты?</p>
<input data-right=»верстальщик»>
</div>
<div>
<p>Самый популярный CSS-фреймворк?</p>
<input data-right=»Bootstrap»>
</div>
Структура разметки будет создаваться в цикле for. of. Укажем какие элементы мы хотим создать: div, p, input. Через метод appendChild() добавим в test блок div. Затем в блок div добавим теги p и input. Правильный ответ будет хранится в дата-атрибуте инпута.
for (let question of questions) <
let div = document.createElement('div');
test.appendChild(div);
let p = document.createElement('p');
p.innerHTML = question.text;
div.appendChild(p);
let input = document.createElement('input');
input.dataset.right = question.right;
div.appendChild(input);
>
В разметку мы поместим контейнер #test, куда будут попадать сгенерированные div блоки и кнопку. По нажатию на кнопку запустится проверка на правильность ответов.
// HTML
<div >сюда попадут сгенерированные теги</div>
<button >Проверить</button>
Получим блок с тестом по его идентификатору.
let test = document.querySelector('#test');
Границы полей с правильными ответами покрасим в зеленый цвет, а с неправильными ответами, в красный.
// CSS
.correct <
border: 2px solid green;
>
.incorrect <
border: 2px solid red;
>
Для проверки правильных ответов, сначала обратимся к нашей кнопке по селектору. Привяжем к кнопке событие: при клике по кнопке выполнится функция, которая переберет все инпуты.
let button = document.querySelector('#button');
button.addEventListener('click', function() <
let inputs = document.querySelectorAll('#test input');
Запускаем цикл for. of для перебора инпутов. У каждого инпута считываем значение, которое ввел пользователь. В условии if-else сверяем ответ пользователя с правильным ответом, обратившись через объект dataset. Если ответ правильный, то к инпуту добавится класс correct с зеленой рамкой. Если ответ неправильный, то добавится класс incorrect и покрасит границы инпута в красный цвет. Добавляем классы через объект classList и метод add. Перед каждым новым проходом цикла, все добавленные классы нужно удалять. Иначе на элементе будут висеть два класса одновременно, что недопустимо.
for (let input of inputs) <
input.classList.remove('correct'); // удаление класса
input.classList.remove('incorrect'); // удаление класса
if (input.value == input.dataset.right) <
input.classList.add('correct');
> else <
input.classList.add('incorrect');
>
>
>);

Тесты на JavaScript не защищены от недобросовестного пользователя, который легко может подсмотреть ответы в коде. Поэтому тесты на JavaScript больше носят развлекательный характер. Реальные тесты, проверяющие знания например у школьников, следует делать на другом языке программирования или хранить ответы в базе данных и вытаскивать их AJAX-ом.
Создание учебного теста с ответами при помощи HTML и JavaScript
В статье описывается последовательное создание учебного теста. Если вы не хотите читать о программировании, то сразу переходите в раздел с инструкциями по изменению теста и его загрузки.
Содержание статьи.
Создание простого теста
Развитие информационных технологий и дистанционного образования приводит к необходимости создания электронных учебных тестов. Многие учителя и преподаватели сталкиваются с проблемой создания учебных тестов. Главная сложность решения данной задачи в том, что при создании таких электронным материалов требуется знание HTML и jаvascript.
Как решить эту проблему. Учитель может воспользоваться онлайн конструктором тестов или же попытаться создать тест самостоятельно на основе использования шаблона. Именно второй вариант мы рассмотрим в данной статье.
Мы сформируем простой шаблон, который можно будет потом размножить на несколько файлов и каждый превратить в отдельный тест.
Допустим имеется несложный математический тест, состоящий из нескольких задач по математике:
- 4*12 +7 =
- 7-8*2 =
- 34*2 + 17 =
Примеры нужно вывести на экран и дать ученику возможность ввести ответ, дальше сравнить ответ с правильным и показать ученику процент правильно выполненного задания.
Сначала создадим HTML код задач:
<p>4*12 + 7 = <input type=”text” ><p>7-8*2 = <input type=”text” ><p>34*2 + 17 = <input type=”text” ><button onclick=”proverit();”>Проверить</button>
<div >
Напротив каждой задачи учебного теста мы подставили поле для ввода текста. Подробнее о различных полях в HTML читайте в статье по ссылке. В конце мы добавили кнопку, при нажатии на которую должна произойти проверка того, что набрал ученик в ответах текста.
Обратите внимание на идентификаторы “z_1”,”z_2” и “z_3”. Если вам нужно добавить задачу 4, то нужно просто скопировать последнюю строку с задачей, заменить условие и в поле идентификатора написать “z_4”.
В последней строке мы покажем результат выполнения заданий после проверки.
На следующем этапе нужно создать jаvascript код, который сравнит то, что набрал ученик с правильными ответами и подсчитает процент выполнения задач.
pr_otv_zadachi_1 = 55;
pr_otv_zadachi_2 = -9;
pr_otv_zadachi_3 = 85;
Первые три строки будут содержать правильные ответы. Четвертая и последующие задачи в тест добавляются путем копирования последней строки с ответом, подстановки числа 4 вместо 3 и указанием правильного ответа.
Теперь нужно узнать то, что ввел ученик в ответах. Для этого используем следующий код.
otv_uch_1 = document.getElementById(‘z_1’).value;
otv_uch_2 = document.getElementById(‘z_2’).value;
otv_uch_3 = document.getElementById(‘z_3’).value;
Четвертая задача будет означать новую строку с заменой цифр 3 на 4.
Далее нужно сравнить ответы ученика с правильными ответами. Если ответы будут совпадать, то за каждую задачу теста нужно добавить 1 балл.
ball = 0;
if(otv_uch_1 == pr_otv_zadachi_1) <
ball +=1;
>
if(otv_uch_2 == pr_otv_zadachi_2) <
ball +=1;
>
if(otv_uch_3 == pr_otv_zadachi_3) <
ball +=1;
>
Для добавления задачи 4 вам потребуется скопировать последние три строки и заменить цифры в них на 4.
Теперь нужно посчитать процент правильных ответов.
В этой строке мы указываем сколько всего задач в учебном тесте. Если вы добавили еще, то нужно исправить эту цифру.
procent_vip = ball/vsego_zadach * 100;
Затем нужно вывести ответ на экран.
document.getElementById(‘rezultat’).innerHTML = “Задания выполнены верно на ”+procent_vip+”%.”;
Вот и все. Теперь объединим весь код в одну HTML страницу.
<html>
<head><title>Тест из нескольких задач по математике</title>
<style>
p <
font-size:24px;
>
input <
font-size:24px;
>
</style>
</head>
<body style=»background-color:#d9ffd6;»>
<p>Выполните задания теста:</p>
<p>4*12 + 7 = <input type=»text» ></p>
<p>7-8*2 = <input type=»text» ></p>
<p>34*2 + 17 = <input type=»text» ></p>
<button onclick=»proverit();»>Проверить</button>
<div ></div>
<script>
function proverit()<
pr_otv_zadachi_1 = 55;
pr_otv_zadachi_2 = -9;
pr_otv_zadachi_3 = 85;
otv_uch_1 = document.getElementById(‘z_1’).value;
otv_uch_2 = document.getElementById(‘z_2’).value;
otv_uch_3 = document.getElementById(‘z_3’).value;
ball = 0;
if(otv_uch_1 == pr_otv_zadachi_1)<
ball +=1;
>
if(otv_uch_2 == pr_otv_zadachi_2)<
ball +=1;
>
if(otv_uch_3 == pr_otv_zadachi_3)<
ball +=1;
>
vsego_zadach = 3;
procent_vip = ball/vsego_zadach * 100;
document.getElementById(‘rezultat’).innerHTML = «Задания выполнены верно на «+procent_vip+»%.»;
>
</script>
</body>
</html>
Я добавил фоновый цвет на всю страницу, а также увеличил шрифт текста.
Вот и весь код учебного теста с ответами на HTML. Ниже вы можете скачать этот файл. Используйте данную инструкцию для того, чтобы увеличить или уменьшить количество задач.
Скачать шаблон теста. Простой вариант
Скачать файл: Шаблон теста [712 b] (cкачиваний: 4977)
Ниже вы можете скачать расширенную версию теста.
Разделение вопросов теста. Добавление кнопки «Следующий вопрос»
Нам нужно сделать так, чтобы единовременно отображался только один вопрос. А для переключения к следующему вопросу нужно было нажать кнопку «Следующий вопрос».
Для этого добавим каждый вопрос и поле для ответа в отдельные блоки div. Причем для второго и третьего вопросов добавим параметр «display:none» для того, чтобы их скрыть. Для первого указываем параметр «display:block». И для каждого блока подпишем номера вопросов.
Также добавим код кнопки «Следующий вопрос».
Далее на нужно добавить функцию перемещения между вопросами теста.
В первом условии мы проверяем отображается ли второй вопрос, если да, то его нужно скрыть и отобразить третий вопрос и также нужно скрыть саму кнопку переключения между вопросами теста и показать кнопку «Проверить» так как этот вопрос последний. Во втором условии мы проверяем отображается ли первый вопрос теста. Если это так, то нужно его скрыть и показать второй вопрос.
В итоге наш тест выглядит так:



Но в этом варианте добавить новые вопросы в тест будет уже сложнее.
Перенос вопросов и ответов теста в отдельный файл JаvaScript
Для того, чтобы заменить вопросы было проще нужно перенести их и ответы в отдельный файл. Тогда не придется искать эти данные в основном файле. Если вы не программист, то такой поиск будет непростым. Итак мы создаем новый файл data.js и подключаем его к основному html файлу нашего теста. Далее добавляем в него несколько переменных с вопросами и несколько с ответами (с ответами мы переносим из основного файла).
Дальше вместо текста вопросов создаем блоки span.
И прописываем jаvascript код постановки текста вопросов из переменных после загрузки страницы.
Вот и все. Теперь, для того, чтобы заменить текст вопросов теста и ответы к нему вам потребуется лишь отредактировать файл data.js. Аналогично добавим название теста:
Шифрование ответов теста
В программе учебного теста, которая у нас получилась есть один недочет. Если учащийся откроет файл «data.js», то он увидит не только тексты вопросов, но и ответы. Поэтому нам нужно зашифровать ответы, чтобы учащийся не смог узнать их.
Для этого используем функцию kodirov. Она выглядит следующим образом:
Аналогично шифруем второй и третий вопросы. После шифрования содержимое файла data.js выглядит следующим образом:
В результате программа проверяет зашифрованные ответы и учащийся не может узнать ответы к вопросам учебного теста.
Вывод результата ответа на каждый вопрос
Наш учебный тест выводит общий результат в процентах. Сделаем так, чтобы еще выводились результаты по каждому вопросу в отдельности. Таким образом можно будет проводить более подробный анализ выполнения теста учащимся.
Для этого нужно модифицировать функцию проверки ответов учащегося.
В результате модификации данной функции выводится верно ли ответил учащийся, а также выводится на экран его ответ. Учитель может сравнить ответ ученика с правильным, а также проанализировать учебную работу.
Таким образом, мы получили полноценный учебный тест, который можно использовать в своей учебной деятельности. Для большего удобства я переместил файл data.js в отдельную папку. Отредактировать файл data.js можно в любом текстовом редакторе, например, «Блокнот».
После последних модификаций, увеличения шрифтов, добавления цвета к ответам получаем следующий полный исходный код html файла:
Результат выполнения теста с ошибкой в третьей задаче показан на рисунке ниже. Также я добавил функцию округления процента выполнения задач «toFixed()».

Ниже вы можете скачать данную программу.
Скачать шаблон теста
Скачать файл: Шаблон теста на 3 вопроса [1.85 Kb] (cкачиваний: 1533)
Скачать файл: Шаблон теста на 10 вопросов [3.61 Kb] (cкачиваний: 1940)
Скачать файл: Шаблон теста на 15 вопросов [3.82 Kb] (cкачиваний: 1679)
Добавление изображений к вопросам теста
Естественно, что кл многим вопросам при создании теста необходимо добавление изображений. Часто нужно добавить изображение вместо текста вопроса. Реализуем данную возможность также через файл data.js. Я буду редактировать самый большой тест из 15 вопросов. Итак, я для каждого вопроса добавлю отдельную переменную и указываю в ней: если изображение есть, то — «да», иначе — «нет».
Обращаю ваше внимание на то, что текст вопроса в случае наличия изображения, я полностью убрал.
Но вы также можете добавить и изображение и текст вопроса.
В данном случае я указал, что в вопросах под номерами 1,4,7 и 15 будут изображения. Поэтому я должен добавить в папку «data» эти изображение. Их названия должны соответствовать (в т.ч. и содержательно) номерам вопросов: «01.jpg», «04.jpg», «07.jpg» и «15.jpg».
В программный код основного файла я добавил условия, которые проверяют переменные. Если есть ли изображение, то одно подгружается к вопросу теста. Пример такого кода для первого вопроса:
Скачать шаблон теста с изображениями
Перемешиваем вопросы теста в случайном порядке
В случае, когда тест выполняются сразу несколькими учениками в классе, которые сидят рядом я сталкивался с проблемой, когда одни смотрят, что же отвечают другие, сидящие рядом. Это первая причина перемешивания вопросов. Второй является просто создание большого количества вариантов одного и того же теста.
Данные манипуляции несколько усложняют программу. Для этого потребуется создать массив, поместить в него все вопросы, изображения и ответы, а затем перемешать все в случайном порядке.
При этом файл «data.js» я не редактировал.
Так выглядит переменная,в которую помещен массив:
Далее нужно перемешать элементы массива и подставить данные в ячейки для вопросов. Для перемешивания я использую функцию
В файл data.js я добавляю новую переменную, в которой можно указать — перемешивать вопросы или нет («да» или «нет»).
Пример вывода вопроса в файле html:
Загрузить тест с возможностью перемешивания вопросов вы можете по ссылке ниже.
Так как вопросы перемешиваются, то в результат работы программы я добавил вывод не только ответов учащегося, но и текста вопросов. Все это я объединил в одну таблицу.
Скачать шаблон теста с изображениями
Визуальное оформление программы тестирования
Все основные функции в тест добавлены. Теперь перейдем к оформлению программы учебного теста. Для сокращения времени работ по оформлению я использую бесплатную библиотеку bootstrap.
Добавлены классы библиотеки и заменены практические все свойства по оформлению как вопросов теста, так и таблицы вывода результата.
Итак, сам тест выглядит следующим образом:
А таблица ответов выглядит следующим образом:
Обратите внимание, что при помощи библиотеки bootstrap я также добавил шкалу, отображающую процентное соотношение верно выполненных задач теста.
Итак, последнюю версию (на данный момент) уже визуально оформленного теста вы можете скачать по ссылке ниже.
[banner_in_full_story_top_stat]
Скачать полную версию шаблона теста

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