Jasmine результаты в HTML
Программирование на стороне клиента давно стало нормой, а объем 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 являются:

  1. describe - определение набора тестов, наборы могут быть вложенными
  2. it - определение теста внутри любого набора тестов.
  3. 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.

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

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

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

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

Ссылки:

github.com/pivotal/jasmine – страница проекта на GitHub
github.com/inex-finance/blog-examples/tree/master/jasmine – примеры кода из данной статьи


Тэги dev, jasmine, javascript
Опубликовано в 25 Январь 2013, 13:41
Изменен в 31 Январь 2013, 13:48

comments powered by Disqus