Testowanie aplikacji

@MichalZalecki

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 narzędzi

Read
Green
Refactor

Testy jednostkowe

Obejmują najmniejsze funkcjonalne jednostki

(Testy jednostkowe)

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

(Testy jednostkowe)

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

(Testy jednostkowe)

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

(Testy jednostkowe)

Szybkie w wykonaniu*

(Testy jednostkowe)

Testy End2End

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

(E2E)

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

(E2E)

Uwzględniają zależności

(E2E)

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

(E2E)

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

(E2E)

Testy jednostkowe

  • Najmniejsze funkcjonalne jednostki
  • Eliminują zależności 
  • Szczegółowe informacje
  • Szybkie w wykonaniu

Testy
End-to-End

  • Testują aplikacje jako ogół
     
  • Uwzględniają zależności
  • Ogólne informacje
  • Długie w wykonaniu

ngMock

$exceptionHandlerProvider
$exceptionHandler
$httpBackend
$interval
$log
$timeout
$rootScope.Scope
angular.mock.TzDate
angular.mock.dump
angular.mock.inject
angular.mock.module

ngMockE2E

$httpBackend
describe 'A suit', ->

  arr = null

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

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

  it 'should have an awesome array', ->
    expect(arr).toEqual jasmine.any Array
    expect(arr.length).toEqual 3
    expect(arr).toContain 'awesome'
    expect(arr).not.toContain 'it sucks'
# moment-factory.coffee

angular.module 'moment.moment-factory', []

.factory 'moment', ->
  window.moment
# moment-factory_test.coffee

describe 'moment', ->

  beforeEach module 'moment.moment-factory'

  it 'should be moment.js', inject (moment) ->
    expect(moment).toEqual jasmine.any Function
    expect(moment).toEqual window.moment
# moment-factory_test.coffee

describe 'moment', ->

  moment = null

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

  it 'should be moment.js', ->
    expect(moment).toEqual jasmine.any Function
    expect(moment).toEqual window.moment
# moment-filter.coffee
angular.module 'moment.moment-filter', []

.filter 'moment', [ 'moment', (moment) ->
  (input, from, to = 'DD-MM-YYYY') ->
    moment(input, from).format(to) ]
# moment-filter_test.coffee
describe 'momentFilter', ->

  beforeEach module 'moment'

  it '[...] default DD-MM-YYYY format', inject ($filter) ->
    expect($filter('moment')('2015-02-23', 'YYYY-MM-DD'))
      .toEqual('23-02-2015')

  it 'should work with custom formats', inject ($filter) ->
    expect($filter('moment')('2015-02-23 10:35',
    'YYYY-MM-DD H:mm', 'Ha, Do MMM YY'))
      .toEqual('10am, 23rd Feb 15')

{ ... }

describe 'GitHub Repos', ->

  textfield = btnGit = repos = msg = null

  beforeEach ->
    browser.get 'http://localhost:8080/app/#/github-repos'

    textfield = element(By.model("user.name"))
    btnGit = element(By.css(".btn-default"))
    repos = element.all(By.repeater('repo in repos'))
    msg = element(By.exactBinding('msg'))

  it '[...] find user repos and set the message', ->
    textfield.clear().sendKeys 'MichalZalecki'
    btnGit.click()
    browser.waitForAngular()
    expect(repos.count()).toBeGreaterThan(0)
    repos.count().then (count) ->
      expect(element(By.css('h2')).getText())
        .toEqual "Found #{count} repos"

{ ... }

Pytania?

Michał Załęcki
@MichalZalecki
michalzalecki.com

Anguloffee

git clone https://github.com/MichalZalecki/anguloffee
Made with Slides.com