Всем нравится волшебство, которое Javascript предоставляет на ваших веб-страницах. Он открывает совершенно новый уровень функциональности вашей скучной веб-страницы. При разработке веб-приложения с использованием рельсов я также познакомился с этой магией. Я использовал эту пикси-пыль во всех своих представлениях, но проблема возникла, когда ее нужно было протестировать. У меня было тяжелое время тестирования, но оно также многому меня научило.

В этом блоге я сосредоточусь на How to части тестирования. Я использовал фреймворк Jasmine для спецификации всех файлов JS. Итак, давайте начнем!

  1. Добавить jasmine в качестве зависимости. Rails обрабатывает зависимость через Gemfile. В Gemfile добавьте строку ниже
    gem 'jasmine', '3.1.0'
    и запустите
    $ bundle install
  2. Настройка 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 и его особенностей.

УДАЧИ ТЕСТИРОВАНИЯ!!