Testowanie z Jasmine, CoffeeScript i AngularJS

Michał Załęcki
@MichalZalecki
michalzalecki.com

Testowanie to...

strata czy inwestycja czasu?

Po co testujemy?

Testy znacząco ułatwiają refaktoryzację i przyczyniają się do mniejszej ilości bugów

Testy są dobrym źródłem informacji, stanowią świetną formę dokumentacji technicznej

Testy w procesie refaktoryzacji przyczyniają się do oszczędności czasu 

Testy są pomocne w procesie przenoszenia kodu między aplikacjami

Testy pozytywnie wpływają na kulturę organizacji pracy

Testy to świetny sposób na poznanie nowych bibliotek

Testy jednostkowe

Obejmują najmniejsze funkcjonalne jednostki

(Unit Tests)

Niezależne od dostępu do sieci, bazy danych, systemu pików itd.

(Unit Tests)

Eliminują zależności poprzez makiety
(mock-upy)

(Unit Tests)

Dostarczają szczegółowej informacji o błędach

(Unit Tests)

Szybkie w wykonaniu

(Unit Tests)

Testy End2End

Testują aplikacje jako ogół, sprawdzają
"data-flow" między komponentami

(E2E Tests)

Działają w środowisku możliwie najbliższym produkcyjnemu

(E2E Tests)

Uwzględniają zależności

(E2E Tests)

Informują (tylko)
o wystąpieniu błędu

(E2E Tests)

Dłuższe w wykonaniu od testów jednostkowych

(E2E Tests)

Testy jednostkowe

  • Obejmują najmniejsze funkcjonalne jednostki
  • Niezależne od dostępu do sieci, bazy danych, systemu pików itd.
  • Eliminują zależności 
    poprzez makiety (mock-upy)
  • Dostarczają szczegółowej informacji o błędach
  • Szybkie w wykonaniu

Testy
End-to-End

  • Testują aplikacje jako ogół, sprawdzają data-flow między komponentami
  • Działają w środowisku możliwie najbliższym produkcyjnemu
  • Uwzględniają zależności
  • Informują o wystąpieniu błędu
  • Dłuższe w wykonaniu od testów jednostkowych

Read
Green
Refactor

foo = (txt) -> "#{txt} bar"





str = foo "Foo"

obj = 
  foo: 1
  bar: 2
var foo, obj, str;

foo = function(txt) {
  return "" + txt + " bar";
};

str = foo("Foo");

obj = {
  foo: 1,
  bar: 2
};
class Person
  constructor: (@name) ->
  sayHi: ->
    "#{@name} is saying hi!"

foo = new Person "Foo"
bar = new Person "Bar"
alert foo.sayHi()
alert bar.sayHi()
var Person, bar, foo;

Person = (function() {
  function Person(name) {
    this.name = name;
  }
  Person.prototype.sayHi = 
    function() {
      return "" + this.name + 
             " is saying hi!";
    };
  return Person;
})();

foo = new Person("Foo");
bar = new Person("Bar");
alert(foo.sayHi());
alert(bar.sayHi());
describe 'A suit', ->

  arr = null

  beforeEach ->
    arr = ['super', 'awesome', 'array']

  it 'contains spec with an expectation', ->
    expect(true).toBe true
    expect(true).not.toBe false
    arr.splice(1, 1) # doesn't really matter

  it 'should have awesome array', ->
    expect(arr).toEqual jasmine.any Array
    expect(arr).toContain 'awesome'
    expect(arr).not.toContain 'it sucks'
'use strict'

describe 'moment.moment-factory', ->

  moment = null

  beforeEach module 'moment.moment-factory'
  beforeEach inject (_moment_) ->
    moment = _moment_

  it 'shoud be windows.moment', ->
    expect(moment).toEqual window.moment
    expect(moment).toEqual jasmine.any(Function)
describe 'Demo page', ->

  beforeEach ->
    browser.get 'http://testing-angularjs-michalrazorzalecki.c9.io/app/'

  it 'should have a title', ->
    expect(browser.getTitle())
      .toEqual 'Testing AngularJS with Jasmine and CoffeeScript'

  it 'should have 5 .alert', ->
    expect(element.all(By.css '.alert').count()).toBe 5

  it 'should have .alert .close button which can close the alert', ->
    alertDism = element.all By.css '.alert-dismissible'
    expect(alertDism.count()).toBeGreaterThan 0
    element.all(By.css '.alert .close').click()
    expect(alertDism.count()).toBe 0

Anguloffee

git clone --depth=1 https://github.com/MichalZalecki/anguloffee

deck

By Michał Załęcki

deck

  • 1,644