Введение в Jasmine

в 11:21, , рубрики: bdd, jasmine, javascript, метки: , ,

Введение в Jasmine
Программирование на стороне клиента давно стало нормой, а объем JavaScript кода и его сложность постоянно растут. Часто тестирование применяется только на серверной стороне, но при этом не стоит забывать о тестировании клиентского кода. Для тестирования JavaScript как на стороне клиента, так и для Node.js можно с успехом применять Jasmine.

Jasmine это BDD фреймворк (Behavior-Driven Development — Разработка на Основе Поведений) для тестирования JavaScript кода, позаимствовавший многие черты из RSpec.

Для удобства, будет рассматриваться тестирование в браузере, а для лаконичности примеры приводятся с использованием CoffeeScript (примеры на JavaScript).

Установить Jasmine можно скачав пакет Jasmine standalone. Потребуются файлы:

  • lib/jasmine-*/jasmine.js — сам фреймворк
  • lib/jasmine-*/jasmine-html.js — оформление результатов в виде HTML
  • lib/jasmine-*/jasmine.css — внешний вид результата выполнения тестов
  • SpecRunner.html — файл, который следует открыть в браузере для запуска тестов

Основными ключевыми словами при работе с Jasmine являются:

  • describe — определение набора тестов, наборы могут быть вложенными
  • it — определение теста внутри любого набора тестов
  • expect — определяет ожидания, которые проверяются в тесте

Ключевые слова describe и it являются обычными вызовами функций, которым передаются два параметра. Первый — название группы или теста, второй — функция содержащая код. Простой пример для ясности:

describe "Набор тестов", ->
  it "проверка ожиданий", ->
    expect(1 + 2).toBe(3)

Для того чтобы отключить выполнение набора тестов или конкретного теста, необходимо воспользоваться ключевыми словами xdescribe и xit соответственно.

describe "Отключение", ->
  xdescribe "отключенный набор тестов", ->
    it "тест не будет запущен, так как набор отключен", ->
      expect(true).toBe(true)
  xit "отключеный тест", ->
    expect(true).toBe(true)

Jasmine имеет стандартный набор ожиданий для проверки результатов:

  it "сравнение с использованием ===", ->
    expect(1 + 2).toBe(3)

  it "сравнение переменных и объектов (включая содержимое)", ->
    a = {x: 8, y: 9}
    b = {x: 8, y: 9}
    expect(a).toEqual(b)
    expect(a).not.toBe(b) # отрицание - a не является b

  it "значение должно быть определено", ->
    expect(window.document).toBeDefined()

  it "значение должно быть не определено", ->
    expect(window.notExists).toBeUndefined()

  it "значение должно быть null", ->
    a = null
    expect(a).toBeNull()

  it "значение должно быть верно", ->
    expect(5 > 0).toBeTruthy()

  it "значение должно быть не верно", ->
    expect(5 < 0).toBeFalsy()

  it "значение должно быть меньше чем", ->
    expect(1 + 2).toBeLessThan(5)

  it "значение должно быть больше чем", ->
    expect(1 + 2).toBeGreaterThan(0)

  it "значение должно быть близко к числу", ->
    expect(1.2345).toBeCloseTo(1.2, 1)

  it "значение должно соответствовать регулярному выражению", ->
    expect("some string").toMatch(/string/)

  it "значение должно содержать", ->
    expect([1, 2, 3]).toContain(2)
    expect("some string").toContain("some")

  it "должно быть вызвано исключение", ->
    func = -> window.notExists.value
    expect(func).toThrow()

Для того чтобы избежать повторения при создании/удалении объектов и загрузки фикстур, необходимых для выполнения тестов, используются функции beforeEach/afterEach. Они запускаются перед/после каждого теста в наборе.

describe "Подготовка/чистка", ->
  val = 0 # определение переменной в зоне видимости набора тестов

  beforeEach ->
    val += 1

  afterEach ->
    val = 0

  it "использует val", ->
    expect(val).toEqual(1)

Jasmine поддерживает тестирование асинхронных вызовов с помощью функций runs и waitsFor.

  • runs — принимает асинхронную функцию для выполнения.
  • waitsFor — принимает первым параметром функцию, которая должна вернуть true, если асинхронный вызов сделанный в runs был выполнен, второй параметр — сообщение об ошибке, третий — время ожидания в миллисекундах.
  describe "Асинхронно", ->
    a = 0

  async = ->
    setTimeout((-> a = 5), 1000)

  it "асинхронное выполнение кода", ->
    runs(-> async())
    waitsFor((-> a == 5), "значение должно быть изменено", 3000)

Рассмотрение работы со “шпионами” spies (mock object) и работы со временем (mock clock) оставим для следующей статьи. Если у Вас есть вопросы или замечания, буду рад на них ответить.

Ссылки:
github.com/pivotal/jasmine — страница Jasmine на GitHub
www.inexfinance.com/en/blog/2013/1/25/jasmine_for_clientside_testing — английский вариант статьи
github.com/inex-finance/blog-examples/tree/master/jasmine — примеры кода из данной статьи

Автор: DeltaSpace

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js