Всем нравится волшебство, которое Javascript предоставляет на ваших веб-страницах. Он открывает совершенно новый уровень функциональности вашей скучной веб-страницы. При разработке веб-приложения с использованием рельсов я также познакомился с этой магией. Я использовал эту пикси-пыль во всех своих представлениях, но проблема возникла, когда ее нужно было протестировать. У меня было тяжелое время тестирования, но оно также многому меня научило.
В этом блоге я сосредоточусь на How to части тестирования. Я использовал фреймворк Jasmine для спецификации всех файлов JS. Итак, давайте начнем!
- Добавить jasmine в качестве зависимости. Rails обрабатывает зависимость через Gemfile. В Gemfile добавьте строку ниже
gem 'jasmine', '3.1.0'
и запустите$ bundle install - Настройка Jasmine Framework: чтобы настроить Jasmine framework .ie. создайте необходимую структуру файлов и папок для запуска вашего проекта
$ rails generate jasmine:install
Это создастjasmine_helper.rb, jasmine.yml & .gitkeepфайлов в вашемspec/javascript/support

НЕОБЯЗАТЕЛЬНО: поскольку некоторые из тестируемых действий могут быть связаны с кликом компонента и другими событиями, нам нужно загрузить этот объект в DOM во время тестирования. Чтобы получить доступ к этим объектам DOM во время тестирования, мы можем использовать jquery. Следовательно, нам нужно включить файл ajquery-build. Сжатую версию файла jquery-build можно скачать здесь и хранить под spec/javascript/support.
На изображении вы можете видеть файл jquery-3.2.1.min.js, хранящийся в папке поддержки под файлом jasmine_helper.rb.
Итак, когда файловая структура создана, давайте скажем jasmine, какие файлы, содержащие код JS, должны быть загружены в браузере перед запуском тестов. Это делается путем упоминания этих файлов в файле jasmine.yml.

3. Запустите Jasmine Server для запуска тестов: запустите тесты javascript, используя следующую команду$ bundle exec rake jasmine
Это запустит jasmine server на localhost:8888. Как только сервер jasmine заработает, откройте http://localhost:8888 в браузере. Вы сможете увидеть жасминовый набор в своем браузере.

Советы:
* Чтобы проверить, все ли ваши js-файлы загрузились в браузере, щелкните правой кнопкой мыши в любом месте окна и выберитеView Source. Откроется новая вкладка, в которой будут показаны все файлы, загруженные в браузер для запуска тестов.
* Все тесты запускаются в браузере, поэтому все файлы, которые вы хотите протестировать, вместе со всеми необходимыми зависимостями должны загружаться в браузере. Путь к этим файлам должен быть указан вjasmine.yml.
4. Наконец-то! фактическая часть тестирования🙏
Все ваши файлы спецификаций находятся под spec/javascript.
Здесь я расскажу о двух типах вызовов методов js, которые часто используются во внешнем интерфейсе.
4.1. После полной загрузки пользовательского интерфейса (окна/документа) пользователь вводит что-то в поле ввода, поэтому для элемента вызывается событие изменения.
4.2. Когда пользователь заполняет форму и нажимает кнопку "Отправить", форма отправляется и перенаправляется на новую страницу.
4.1 Проверка события изменения, вызывающего функцию JS:
Здесь мы взяли элемент ввода с input-type = file и id = csvFile. Если файл выбран с помощью этого элемента ввода, мы намерены проверить, вызывается ли функция onFileChange.
Файл js app/assets/javascripts/tagging.js содержит функцию onFileChange.
function onFileChange() {
// doSomething..
}
$(document).on(‘ready’, function () {
$(‘#csvFile’).change(onFileChange);
});
Нам не нужно загружать весь HTML-файл в DOM, содержащий элемент csvFile. Фикстуры Jasmine помогают нам загружать в DOM только те элементы, которые мы собираемся тестировать, а затем удалять их из DOM после завершения тестирования. Фикстуры — это не что иное, как HTML-файлы, содержащие компоненты, которые вы хотите загрузить в браузер для тестирования. Для вышеупомянутого примера мы создали файл фикстуры, содержащий только элемент csvFile.
Файл: spec/javascript/fixtures/input-csv.html
<div class=”form-group”> <input id=”csvFile” class=”form-control” accept=”.csv” type=”file” /> </div>
Тест выглядит так, как показано ниже, и находится в файле spec/javascript/tagging-spec.js.
describe('Tagging',function(){
it('calls onFileChange listener when a change is detected/triggered in the file input', function () {
loadFixtures('input-csv.html')
spyOn(window,'onFileChange')
$(document).trigger('ready')
$('#csvFile').trigger('change')
expect(window.onFileChange).toHaveBeenCalled()
});
});
Давайте пройдемся по приведенному выше фрагменту один за другим.
- Блоки
descrbeиitиспользуются для определения спецификаций. В то время какdescribeиспользуется для объединения похожих тестов,it— это фактический блок, в котором должны находиться тесты. loadFixtures('input-csv.html')загружает компонент ввода в браузере.spyOn(window.'onFileChange')создает фиктивную функцию «onFileChange» для объекта «окно» в браузере.document.trigger('ready') and ('#csvFile').trigger('change')— это действия, которые должны произойти, чтобы вызватьonFileChange.
Совет:
По умолчаниюreadyзагружается только тогда, когда все ваши тесты запущены и сервер jasmine отображает свой html в браузере со списком всех тестовых файлов .ie. когда DOM будет готов. Но здесь мы хотим, чтобыreadyинициировался раньше, когда наш тест еще выполняется. Поэтому мы принудительно запускаем его с помощьюdocument.trigger('ready').
- Наши триггеры предоставили то, что необходимо для вызова метода onFileChange, но, поскольку мы имитировали метод
onFileChangeс помощьюspyOn, вызывается фиктивный метод. И это делает нашу спецификацию пройденной.
Совет:
Если какая-либо из ваших команд спецификации не работает, попробуйте запустить ее в консоли при просмотре страницы браузера.
4.2 Проверка отправки формы с вызовом функции JS и перенаправлением на новую страницу
Ниже показана функция, которая вызывается, когда пользователь нажимает кнопку отправки в форме.
Файл: app/assets/javascripts/submit.js
function onSubmit(event) {
//doSomething..
}
Соответствующий файл фикстуры, содержащий определение формы.
Файл: spec/javascripts/fixtutres/upload-button.html
<form id="upload-form" class="form" onsubmit="onSubmit(event)" >
<div class="form-group">
<input id="saveCsvUpload" type="submit" value="Upload" class="btn btn-primary" disabled/>
</div>
</form>
ТЕСТ: spec/javascript/submit-spec.js
describe( 'Submit', funciton(){
it('is only called when Upload button is clicked by user', function () {
spyOn(window,'onSubmit')
loadFixtures('upload-button.html')
$('#upload-form').submit()
expect(window.onSubmit).toHaveBeenCalled()
})
});
Точно так же, как мы сделали это для предыдущей спецификации, мы создаем макет onSubmit(event). Обратите внимание, что мы сначала смоделировали кнопку отправки, а затем загрузили прибор. Это потому, что нам нужно определить onSubmitвызванный onsubmit = “onSubmit(event)”до его использования. Теперь, когда в форме вызывается submit(), он будет подтверждать вызов шпионской функции onSubmit.
ПРОБЛЕМА: Если вы запустите сервер jasmine и запустите спецификации, вы увидите, что страница браузера постоянно обновляется. Это потому, что он делает непрерывные вызовы отправки. [Понятия не имею, почему делаются непрерывные звонки. Насколько я понимаю, должен быть сделан только один вызов submit].
Чтобы этого не произошло, нам нужно предотвратить действие по умолчанию .ie. перенаправление на новый URL. Следовательно, вместо просто spyOn(window,tagging) добавьте:
window.tagging = jasmine.createSpy().and.callFake(function(event) {
event.preventDefault();
})
Теперь вместо этого будет вызываться эта поддельная функция, которая предотвращает выполнение действия по умолчанию (отправить + перенаправление на новый URL-адрес).
Дайте мне знать, если что-то было неясно, и я постараюсь сделать все возможное, чтобы исправить это. Я даже открыт для обсуждения Jasmine и его особенностей.
УДАЧИ ТЕСТИРОВАНИЯ!!