Screenshot Testing for Android

Ae116e380166e8841be56b728a169948?s=47 Nikos Linakis
September 24, 2019

Screenshot Testing for Android

Screenshot Testing is a fast, simple, and fun way to develop UI while keeping your sanity and avoid visual regression bugs. In this talk Nikos and Christoforos will explain what is Screenshot Testing and how it protects and speeds up UI development. They’ll point out some common gotchas while paving the road to the “perfect pull-request”.

Ae116e380166e8841be56b728a169948?s=128

Nikos Linakis

September 24, 2019
Tweet

Transcript

  1. SCREENSHOT TESTING NIKOS LINAKIS - CHRISTOFOROS FILIPPOU ANDROID TEAM @XM

    TESTING THE UI AND BEYOND
  2. TESTING • Unit tests for business logic • UI tests

    for business or presentation logic • Robolectric for asserting view state • Espresso for interactions, layout
  3. VISUAL TESTING METHOD SCREENSHOT TESTING

  4. Diff Verify Record COMPARING SCREENSHOTS SCREENSHOT TESTING

  5. WHY DO THIS? SCREENSHOT TESTING • They assert more properties

    than a unit test normally does
  6. SCREENSHOT TESTING EVERYTHING THE LIGHT TOUCHES IS OUR… TEST!

  7. WHY DO THIS? SCREENSHOT TESTING • They assert more properties

    than a unit test normally does • A fast way to see how our view looks while developing • Immediately detect UI breaking changes and avoid regression bugs
  8. MULTIPLE UI CASES SCREENSHOT TESTING

  9. TESTING LANGUAGES SCREENSHOT TESTING

  10. TESTING DEVICES SIZES SCREENSHOT TESTING

  11. TESTING THEMES SCREENSHOT TESTING

  12. SCREENSHOT TESTING

  13. SCREENSHOT TESTING

  14. + KARUMI/SHOT GRADLE PLUGIN SCREENSHOT-TESTS-FOR-ANDROID • Developed and used by

    Facebook • Html report (visual diff of failed tests) • CI friendly
  15. FIRST TEST import org.junit.Test class MyFirstTest { @Test @Throws(Throwable::class) fun

    testRendering() { } }
  16. FIRST TEST import org.junit.Test class MyFirstTest { @Test @Throws(Throwable::class) fun

    testRendering() { val targetContext = getInstrumentation().targetContext val inflater = LayoutInflater.from(targetContext) val view = inflater.inflate(R.layout.market_hours_view, null, false) } }
  17. FIRST TEST import org.junit.Test class MyFirstTest { @Test @Throws(Throwable::class) fun

    testRendering() { val targetContext = getInstrumentation().targetContext val inflater = LayoutInflater.from(targetContext) val view = inflater.inflate(R.layout.market_hours_view, null, false) ViewHelpers.setupView(view).setExactWidthDp(300).layout() } }
  18. FIRST TEST import org.junit.Test class MyFirstTest { @Test @Throws(Throwable::class) fun

    testRendering() { val targetContext = getInstrumentation().targetContext val inflater = LayoutInflater.from(targetContext) val view = inflater.inflate(R.layout.market_hours_view, null, false) ViewHelpers.setupView(view).setExactWidthDp(300).layout() } }
  19. FIRST TEST import org.junit.Test class MyFirstTest { @Test @Throws(Throwable::class) fun

    testRendering() { val targetContext = getInstrumentation().targetContext val inflater = LayoutInflater.from(targetContext) val view = inflater.inflate(R.layout.market_hours_view, null, false) ViewHelpers.setupView(view).setExactWidthDp(300).layout() } }
  20. FIRST TEST import org.junit.Test class MyFirstTest { @Test @Throws(Throwable::class) fun

    testRendering() { val targetContext = getInstrumentation().targetContext val inflater = LayoutInflater.from(targetContext) val view = inflater.inflate(R.layout.market_hours_view, null, false) ViewHelpers.setupView(view).setExactWidthDp(300).layout() Screenshot.snap(view).record() } }
  21. DEMO

  22. THE PERFECT PULL REQUEST

  23. MEDIUM BLOG POST https://medium.com/xmglobal

  24. REFERENCES • https://speakerdeck.com/linakis/screenshot-testing-for-android • https://medium.com/xmtrading/screenshot-testing-101-7dd24ca6b8ce • https://github.com/trading-point/screenshot-testing-android-demo • https://youtu.be/tpHsAx8HSkU •

    https://facebook.github.io/screenshot-tests-for-android/ • https://github.com/Karumi/Shot
  25. THANK YOU QUESTIONS?