Upgrade to Pro — share decks privately, control downloads, hide ads and more …

UI Testing Best Practices - An Expected Journey

UI Testing Best Practices - An Expected Journey

usecase of why writing tests for ui for http://echotu.be
The examples are shown with angular, jasmine.js, karma and phantom.

Oren Farhi

October 30, 2014
Tweet

More Decks by Oren Farhi

Other Decks in Programming

Transcript

  1. Oren Farhi JS Engineer (2006) JS Group Leader @Tikal Speaker

    (Israel & World Wide) github.com/orizens orizens.com JS es6 B
  2. Outline 1. What is UI testing 2. Why Should I

    Test UI 3. Best Practices Patterns Demo App: Echoes Player http://echotu.be (available as a chrome app) github.com/orizens/echoes/tree/angular
  3. Automating The Debug Process 1. Add some “watches” 2. Add

    some “truthy” watches 3. Refresh 4. Try some other input 5. Repeat the “clicks”, “enter”, “keys” in input 6. Refresh
  4. A UI Test = expecting something to be The Goals

    of debugging are: 1. I expect something to be with a value 2. I expect something to be visible on the DOM 3. I expect that click will change the search 4. I expect that a right click will show a context menu, with user permissions visible 5. I expect “<grid model=”items”>” to render a data table in the DOM
  5. Jasmine.js by Pivotal it’s a Standalone BDD framework for testing

    JS code available on github 1. Suites - describe() 2. Specs - it() 3. Expectations -expect() 4. Matchers - .not/.toBe() • Spies • Stubs • Async • skip tests - xit, xdescribe
  6. What is BDD? Behavior Driven Development business perspective - story

    of the code and its goal (stop Balrog from passing)
  7. HTML - container rendered it('should render a dropdown element', function

    () { expect(element.hasClass('dropdown')).toBeTruthy(); });
  8. HTML - items rendered it("should render items if given presets",

    function() { expect( element.find('ul li').length) .toBe( scope.presets.length ); });
  9. HTML - Content is rendered it("should render the label according

    to the 'label' attribute", function() { expect( element.find('.dropdown-toggle').text().trim()) .toBe('Preset') });
  10. Functionality - function called on clicked it("should call a function

    when select has changed",function() { spyOn(scope, 'onPresetChange'); element.isolateScope().handleClick(scope.presets[0]); expect(scope.onPresetChange).toHaveBeenCalled(); });
  11. Functionality using Spy - click it("should call a function with

    the selected item when select has changed", function() { spyOn(scope, 'onPresetChange'); element.isolateScope().handleClick(scope.presets[0]); expect(scope.onPresetChange).toHaveBeenCalledWith(scope.presets [0]); });
  12. Preparing Mocks var mockData = { items: [{snippet: 3}] };

    var url = "https://www.googleapis.com/youtube/v3/search" + "? key=AIzaSyB7fFNreY1UzX1la5arnnAi3ZOyvqOV6kk&maxResults=50&part=s nippet,id";
  13. Functionality using Spy and Fake it("set the feed type when

    changed in YoutubeSearch and perform search", function(){ httpBackend.whenGET(url).respond(mockData); spyOn(scope, 'searchYoutube').and.returnValue('done') spyOn(YoutubeSearchSrv, 'setType').and.callFake(function(){ return 'set'; }); rootScope.$broadcast('feed-type-changed', 'playlist'); scope.$digest(); expect(YoutubeSearchSrv.setType).toHaveBeenCalled(); expect(YoutubeSearchSrv.setType.calls.count()).toEqual(1); expect(scope.searchYoutube).toHaveBeenCalled(); expect(scope.searchYoutube.calls.count()).toEqual(1); })
  14. Mocking Ajax Call it('should set videos after successful search', function()

    { httpBackend.whenGET(url).respond(mockData); scope.searchYoutube(); httpBackend.flush(); expect(scope.videos).toBeDefined(); expect(scope.videos.length).toBe(1); });
  15. E2E with Pioneer.js Feature: Simple Feature Background: Given I visit

    Echoes Player Scenario: Entering Information When I search for "alice in chains live" Then I should see 50 results
  16. What is Good with UI Unit Testing • Adding Features

    won’t break code’s behaviour • promotes writing modular logics • documentation - code intention & functional behavior • Forces writing high quality code - decoupling