29
ТЕСТИРОВАНИЕ JAVASCRIPT КОДА Wednesday, January 30, 13

Javascript testing

Embed Size (px)

Citation preview

Page 1: Javascript testing

ТЕСТИРОВАНИЕ JAVASCRIPT КОДА

Wednesday, January 30, 13

Page 2: Javascript testing

Зачем тестировать javascript?

Мы пишем рабочий код, зачем нам писать ещекакие то тесты?!

Тестировщики и так тестируют функционал!

Wednesday, January 30, 13

Page 3: Javascript testing

Код без тестирования

Wednesday, January 30, 13

Page 4: Javascript testing

Код покрытый тестами

Wednesday, January 30, 13

Page 5: Javascript testing

Писать тесты круто!

Wednesday, January 30, 13

Page 6: Javascript testing

Писать тесты необходимо

1. инструкция для вашего кода (документация)2. уверенность в вашем коде и завтрашнем дне3. эволюция разработчика4. рефакторинг без страха

Wednesday, January 30, 13

Page 7: Javascript testing

Подходы

TDDОписывает юнит, с точки зрения его функциональности

Думаете как работает код.

describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ assert.equal(-1, [1,2,3].indexOf(5)); assert.equal(-1, [1,2,3].indexOf(0)); }) })

BDDОписывает поведение юнита (модуля), как он должен себя вести

Эволюция TDD под требования бизнеса, когда надо говорить о поведении, а не о коде. Это значит, что надо думать не функциями и возвращаемыми значениями, а поведением тестируемой сущности

describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ [1,2,3].indexOf(5).should.equal(-1); [1,2,3].indexOf(0).should.equal(-1); }) })

Wednesday, January 30, 13

Page 8: Javascript testing

•Код должен быть модульным, а не монолитным. Мы пишем тесты для юнита

•Слабая связанность между компонентами

•Один юнит должен решать одну задачу. Ведем разработку методом “Разделяй и влавствуй”

•Тестируем поведение. Нужен контрольный пример идеального поведения

Какой код можно покрыть тестами?

Wednesday, January 30, 13

Page 9: Javascript testing

• Пишем тест, смотрим чтобы тест запускался

• Пишем код.

• Запускаем тест

• Дорабатываем код, чтобы тест был пройден

Как писать тесты? Теория BDD.

Wednesday, January 30, 13

Page 10: Javascript testing

•Не весь код надо покрывать тестами. Определяем что тестируем, а что не тестируем.

• Сложные юниты, связанные с другими юнитами, тестируем методом декомпозиции снизу вверх. Те тестируем обособленные юниты, а потом общий юнит.

Как писать тесты? Теория BDD. Дополнение

Wednesday, January 30, 13

Page 11: Javascript testing

• Jasmine BDD testing framework

• Jasmine-jQuery (помощь для DOM testing)

• SinonJS: spies, mock, fixtures, fakeServer

• TestAcular или Testem (test runner)

• PhantomJS (или любой другой браузер)

•NodeJS (для запуска JS-кода)

Инструментарий

Нужно: Test runner и test framework

Wednesday, January 30, 13

Page 12: Javascript testing

•NodeJS (windows/linux/mac)

• PhantomJS (windows/linux/mac)

• npm -g install testacular (jasmine уже встроен)

• скачиваем jasmine-jquery, sinonjs

• npm -g install coffee-script (удобней писать тесты)

• настраиваем конфиг testacular

Порядок установки

Wednesday, January 30, 13

Page 13: Javascript testing

• basePath = “./” - где находятся все файлы.

• files = [“.*coffee”, “jquery.js” ....] - зависимости, тесты, код

• reporters = [“dots”] - формат отчета

• port = 9090 - где запускается сервер

• autoWatch = false - отключаем мониторинг файлов

• browsers = [“PhantomJS”, “Chrome” ...] - в каких браузерах запускать тесты

• preprocessors = {“**/*.coffee” : “coffee”}

Конфигурируем TestAcular

Wednesday, January 30, 13

Page 14: Javascript testing

Запускаем из консоли

Wednesday, January 30, 13

Page 15: Javascript testing

Настраиваем запуск в IntelliJ IDEA

Wednesday, January 30, 13

Page 16: Javascript testing

Запуск в IntelliJ Idea

Wednesday, January 30, 13

Page 17: Javascript testing

CoffeeScript minimal skills

javascript coffeescript

function test( ) { }function test(a, b, c){ }

test = ->test = (a, b, c) ->

a = {key: “value”} a = key : “value”

test( ) test( )

test(a, b, c) test a, b, c

function( ){ }.bind(this) ( )=>

test.prototype.name test::name

this.name @name

Wednesday, January 30, 13

Page 18: Javascript testing

CoffeeScript minimal skills

Block Stringshtml = """ <div class=”test”> cup of <strong>coffeescript</strong> </div> """

Wednesday, January 30, 13

Page 19: Javascript testing

Jasmine BDD

describe("A suite", function() { it("contains spec with an expectation", function() { expect(true).toBe(true); });});

suites

describe("A suite is just a function", function() { var a;

it("and so is a spec", function() { a = true;

expect(a).toBe(true); });});

Test

Wednesday, January 30, 13

Page 20: Javascript testing

• toBe - сравнение

• toEqual - тождество

• toMatch - регулярка

• toBeDefined / toBeUndefined - существование

• toBeNull

• toBeTruthy - истина

• toBeFalsy - ложь

• toContain - содержит

• not.toBe / not.toBeDefined / not.toBeUndefined / not.toBeNull ..... отрицание

Matchers

Wednesday, January 30, 13

Page 21: Javascript testing

Jasmine. example case 1

describe "my first test case", -> it "test trythy", -> expect(true).toBeTruthy() it "test equal", -> expect(1).toEqual 1 it "test null", -> expect(null).toBeNull() it "test defined", -> b = 100 expect(b).not.toBeUndefined() it "test contain", -> expect("bar").toContain "b" expect("bar").not.toContain "z"

Wednesday, January 30, 13

Page 22: Javascript testing

Jasmine. Setup and Teardown

beforeEach - инициализация ресурсов и выполнение действий необходимых для каждого теста

afterEach - освобождение ресурсов и выполнение действий после каждого теста

Wednesday, January 30, 13

Page 23: Javascript testing

Jasmine. Spies.

Когда не важен результат функции, а важен лишь факт ее вызова на помощь приходят шпионы!spyOn - создаем шпионаtoHaveBeenCalled - вызывался ли онtoHaveBeenCalledWith - вызывался с аргументамиandCallFake - говорим, чтобы вызвал нашу функцию вместо стандартной

Wednesday, January 30, 13

Page 24: Javascript testing

Jasmine. Spies

Для тестирования сложных юнитов, можно создавать fake objects имитирующих поведение реальных объектов

createSpyObj - создает объект с указанными фейковыми свойствами

Wednesday, January 30, 13

Page 25: Javascript testing

Jasmine. Async tests

Для тестирования функций, которые выполняются асинхронно необходим особый подходwaitFor - ждем указанное время. Возвращает Boolean, который говорит о прохождении теста, либо fail при окончании указанного промежутка времени

runs - выполнение инструкций. Зависит от waitFor

Анимации, таймауты, ajax и тд и тп.

Wednesday, January 30, 13

Page 26: Javascript testing

• stubs - подменяет вызов функции

• useFakeXMLHttpRequest - подменяет нативный request на фейковый

• fakeServer (.create/.restore) - создает фэйковый сервер и проксирует через него все запросы

SinonJS. или как тестировать ajax requests, mocks

Wednesday, January 30, 13

Page 27: Javascript testing

sinon.fakeServer.create()

1. создаем сервер server = sinon.fakeServer.create( )2. добавляем мапинг запросов server.respondWith3. делаем запрос $.get4. отдаем запрос фейковым сервером server.respond( )

Wednesday, January 30, 13

Page 28: Javascript testing

Тестирование DOM.

1. тестировать все не нужно. Достаточно проверить наличие элемента и его атрибуты

2. Создаем html fixture: переменная или test page

3. перед каждым тестом вставляем его в DOM

4. после каждого теста очищаем DOM

Wednesday, January 30, 13

Page 29: Javascript testing

Спасибо за внимание!

Wednesday, January 30, 13