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

PhantomCSS - Complete UI Testing

James Cryer
October 31, 2013

PhantomCSS - Complete UI Testing

PhantomCSS has become an essential tool at Huddle for developing and refactoring UI with visual tests. This talk explains the background of why I built PhantomCSS and how this fits in with conventional ideas of unit testing and test-driven development.

https://github.com/Huddle/PhantomCSS

Presented at http://www.frontendlondon.co.uk/ on 31st Oct 2013

James Cryer

October 31, 2013
Tweet

More Decks by James Cryer

Other Decks in Technology

Transcript

  1. P H A N T O M C S S

    C O M P L E T E U I T E S T I N G
  2. PhantomCSS is a CasperJS module for automating visual regression testing

    with PhantomJS and Resemble.js. For testing Web apps, live style guides and responsive layouts
  3. Test coverage of UI without implementation coupling. Tests that reflect

    the designer model, not the developer model. Graphical idioms not functional primitives.
  4. Developed at Huddle. Tools that help people in business work

    together to create and share content. At its core, a thick client web application for files.
  5. • Our Selenium end-to-end tests were our only UI tests.

    We needed fast UI tests, independent of end-to-end • Jasmine tests supported and hindered JavaScript development in equal measure. We wanted to refactor our app without needing to change all the tests • Refactoring CSS involved manual regression testing. We wanted automated CSS tests • Our Selenium end-to-end tests were our only UI tests. We needed fast UI tests, independent of end-to-end • Jasmine tests supported and hindered JavaScript development in equal measure. We wanted to refactor our app without needing to change all the tests • Refactoring CSS involved manual regression testing. We wanted automated CSS tests
  6. Unit Service UI Test Pyramid - M I K E

    C O H N , S U C C E E D I N G W I T H A G I L E ( 1 )
  7. Unit Service UI/end-to-end Not a test pyramid UI tests are

    slow, without clear separation of functional tests
  8. Unit tests provide fast automated assertions of expected state or

    behaviour. Each test runs independently of each other. A unit test for UI should test the expected result of JS, HTML and CSS as a single concern S Y S T E M U N D E R T E S T J A VA S C R I P T H T M L C S S F I X T U R E I N T E R FA C E
  9. Tests for rendered UI provide implicit coverage of CSS, HTML

    and JavaScript regardless of technology choices – M A R T I N F O W L E R ( 2 ) “A classic test only cares about the final state - not how that state was derived. ” J A VA S C R I P T H T M L C S S F I X T U R E I N T E R FA C E
  10. Isolating the system under test makes feedback faster and tests

    less fragile. Without speed and confidence, code is perceived to be less malleable and tests become worthless J A VA S C R I P T H T M L C S S F I X T U R E I N T E R FA C E
  11. casper.addListener('page.initialized', function(){! ! phantomxhr.fake({! ! ! url: "/api/coffee/list",! ! !

    responseBody: {! ! ! ! types: [! ! ! ! ! {name: 'Espresso'},! ! ! ! ! {name: 'Latte'},! ! ! ! ! {name: 'Cappuccino'}! ! ! ! ]! ! ! }! ! });! ! ! casper.removeListener('page.initialized');! });! ! casper.! ! start( “http://my.coffee.local” ).! ! then(function(){! ! ! casper.click('#coffee-machine-button');! ! ! ! ! ! casper.waitForSelector('#myModal:not([style*="display: none"])',! ! ! ! function success(){! ! ! ! ! phantomcss.screenshot('#myModal', 'coffee machine dialog');! ! ! ! },! ! ! ! function timeout(){! ! ! ! ! casper.test.fail('Should see coffee machine');! ! ! ! }! ! ! );! ! }); casper.addListener('page.initialized', function(){! ! phantomxhr.fake({! ! ! url: "/api/coffee/list",! ! ! responseBody: {! ! ! ! types: [! ! ! ! ! {name: 'Espresso'},! ! ! ! ! {name: 'Latte'},! ! ! ! ! {name: 'Cappuccino'}! ! ! ! ]! ! ! }! ! });! ! ! casper.removeListener('page.initialized');! });! ! casper.! ! start( “http://my.coffee.local” ).! ! then(function(){! ! ! casper.click('#coffee-machine-button');! ! ! ! ! ! casper.waitForSelector('#myModal:not([style*="display: none"])',! ! ! ! function success(){! ! ! ! ! phantomcss.screenshot('#myModal', 'coffee machine dialog');! ! ! ! },! ! ! ! function timeout(){! ! ! ! ! casper.test.fail('Should see coffee machine');! ! ! ! }! ! ! );! ! }); Create an API stub to feed fake data to the UI Generate a screenshot and compare to existing
  12. Write a failing test Hack the code to make the

    test pass Refactor the code Keep hacking until it looks good Add a visual test Visual tests can support TDD and refactoring of the entire UI not just the styling – K E N T B E C K , T E S T- D R I V E N D E V E L O P M E N T ( 3 )
  13. 1. Succeeding with Agile: Software Development Using Scrum - Mike

    Cohn 2. http://martinfowler.com/articles/mocksArentStubs.html - Martin Fowler 3. Test-Driven Development - Kent Beck
  14. P H A N T O M C S S

    C O M P L E T E U I T E S T I N G https://github.com/Huddle/PhantomCSS @ J A M E S C RY E R