Boost the Quality of Your App with Firebase (May 22, 2018 Londroid)

Boost the Quality of Your App with Firebase (May 22, 2018 Londroid)

3acd4fb373289e71fd7ebfb287a75a3b?s=128

Doug Stevenson

May 24, 2018
Tweet

Transcript

  1. 2.

    50% Stability & bugs When leaving a 1 star review,

    50% of the time the user mentions the app stability and bugs Google analysis on Play reviews, top 10 English speaking countries, last 365 days of reviews @CodingDoug
  2. 4.
  3. 5.
  4. 6.

    Firebase Test Lab Test Artifacts • Logcat (crashes) • Videos

    • Screenshots • Performance
 CPU
 memory
 network ingress/egress @CodingDoug
  5. 7.

    Instrumented Tests • Specific to Android • Focus on the

    user story / use case • Espresso / UI Automator • Adds extensions to JUnit • Android Testing Support Library: goo.gl/xSxzoj • Testing Codelab: goo.gl/RHdFBY @CodingDoug
  6. 8.

    @RunWith(AndroidJUnit4.class) public class NotesScreenTest { @Rule public ActivityTestRule<NotesActivity> mNotesActivityTestRule =

    new ActivityTestRule<>(NotesActivity.class); @Test public void clickAddNoteButton_opensAddNoteUi() throws Exception { // Click on the add note button onView(withId(R.id.fab_add_notes)).perform(click()); // Check if the add note screen is displayed onView(withId(R.id.add_note_title)).check(matches(isDisplayed())); } } @CodingDoug
  7. 9.

    (Local) Unit Tests • Runs fast on your computer •

    Focus on testing individual classes and methods • Dependency injection / object mocking @CodingDoug
  8. 11.

    Protip: Run your unit tests along with instrumented tests android

    {
 sourceSets {
 androidTest {
 java.srcDirs += "src/test/java"
 }
 }
 } testImplementation 'org.mockito:mockito-core:2.17.0'
 androidTestImplememntation 'org.mockito:mockito-android:2.17.0' @CodingDoug
  9. 12.

    Protip: Enable StrictMode when running in Test Lab Turn StrictMode

    violations into actionable crash reports in Test Lab. @CodingDoug
  10. 13.

    // During Application.onCreate() or ContentProvider.onCreate() private void enableStrictMode() { if

    (shouldEnableStrictMode()) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .penaltyDeath() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .penaltyDeath() .build()); } } @CodingDoug
  11. 15.

    private boolean shouldEnableStrictMode() { ContentResolver resolver = context.getContentResolver(); String isRunningInTestLab

    = Settings.System.getString(resolver, "firebase.test.lab"); return BuildConfig.DEBUG || "true".equals(isRunningInTestLab); } @CodingDoug
  12. 16.

    // https://issuetracker.google.com/issues/36951662 private void workaroundEnableStrictMode() { enableStrictMode(); if (Build.VERSION.SDK_INT >=

    16) { // restore strict mode after onCreate() returns. new Handler().postAtFrontOfQueue(new Runnable() { @Override public void run() { enableStrictMode(); } }); } } @CodingDoug
  13. 18.

    Espresso Test Recorder • Android Studio
 Menu → Run →

    ⚫︎Record Espresso Test • Interact with your app • Generates Espresso code to match your actions @CodingDoug
  14. 22.
  15. 23.

    Robo Test • Only an APK with is required •

    Automatically logs in with Google Auth • Can pre-fill form fields (e.g. user/pass login, search) • Configure maximum crawl depth and timeout • Algorithm improves over time • Additional test artifact: Activity map • Roboscript @CodingDoug
  16. 25.
  17. 26.

    Game Loop Test (beta) • Sequence of scenarios driven by

    Android Intents • Performance += FPS • Game Loop Codelab: goo.gl/sn4RNp • “Mechahamster” sample game • Project home: goo.gl/8chQ8p • Test Lab Guide: goo.gl/16xSPn @CodingDoug
  18. 28.
  19. 30.
  20. 32.

    gcloud firebase test android run \ --type instrumentation \ --app

    app-debug-unaligned.apk \ --test app-debug-test-unaligned.apk \ --device model=Nexus6,version=21,orientation=portrait \ --device model=Nexus7,version=19,orientation=landscape @CodingDoug
  21. 33.

    Community Support for testing with CI • Walmart’s “Flank” for

    sharding tests
 goo.gl/5ApxVU • Circle CI integration
 goo.gl/xoPFqY @CodingDoug
  22. 34.
  23. 35.

    Billing for Firebase Test Lab • Spark and Flame payment

    plans: daily limits • Virtual devices: 10 tests/day • Physical devices: 5 tests/day • Blaze payment plan: per-minute billing • Virtual devices: $1/device/hour • Physical devices: $5/device/hour @CodingDoug
  24. 38.
  25. 39.

    Crashlytics features • Unity support • NDK support • Search

    • Webhooks • Cloud Functions trigger • Integration with Google Analytics for Firebase • Integration with Slack (new!) @CodingDoug
  26. 40.

    public interface UncaughtExceptionHandler { /** * Method invoked when the

    given thread terminates due to the * given uncaught exception. * <p>Any exception thrown by this method will be ignored by the * Java Virtual Machine. * @param t the thread * @param e the exception */ void uncaughtException(Thread t, Throwable e); } @CodingDoug
  27. 41.

    public class MyHandler implements Thread.UncaughtExceptionHandler { private final Thread.UncaughtExceptionHandler mPriorExceptionHandler;

    public MyHandler(Thread.UncaughtExceptionHandler prior) { mPriorExceptionHandler = prior; } @Override public void uncaughtException(Thread thread, Throwable throwable) { // Deal with throwable here if (mPriorExceptionHandler != null) { mPriorExceptionHandler.uncaughtException(thread, throwable); } } } @CodingDoug
  28. 43.
  29. 45.

    60% Speed, design & usability When leaving a 5 star

    review, 60% of the time the user mentions the speed, design or usability Google analysis on Play reviews, top 10 English speaking countries, last 365 days of reviews @CodingDoug
  30. 47.

    Systrace Advantages • Lots of detail • Custom traces Disadvantages

    • App runs slow • You typically have to know what you're looking for • Can't collect data from the wild, only connected devices @CodingDoug
  31. 48.
  32. 49.

    Firebase Performance Monitoring • Runs in production • Negligible overhead

    • Automatic and Custom traces • Automatic HTTP/S traffic metrics @CodingDoug
  33. 50.

    Trace • A report for a period of time with

    a well-defined beginning and end • Nominally has a duration • Also may contain “metrics" for performance-related events during the trace @CodingDoug
  34. 51.

    Automatic Traces - no coding necessary! • App Start (cold)

    • Screen (each Activity start / stop) • App in foreground • App in background @CodingDoug
  35. 54.

    Metrics • Associate a string/int pair to a Trace •

    Typically better to measure ratios than absolute values • Abs value if you want to compare similar metrics between traces cache_hit++ cache_miss++ dropped_frames += 10 @CodingDoug
  36. 56.

    Android Vitals - get clues for what to measure •

    In the Google Play Console: goo.gl/rkztG1 • Performance-related stats • Slow rendering (jank) • Frozen frames • Stuck WakeLocks @CodingDoug
  37. 57.

    Automatic HTTP/S transaction metrics • Response time • Payload size

    • Success rate • URL pattern globbing
 
 yourcdn.com/*.jpg
 api.yourdomain.com/v1/users/*
 api.yourdomain.com/v1/users/*/history/* @CodingDoug
  38. 58.

    HTTP/S transaction metrics breakdown • App version • Device •

    Country • OS level • Carrier • Radio @CodingDoug
  39. 60.

    How HTTP/S monitoring works Build time bytecode manipulation (with ASM)

    URL url = new URL("https://firebase.google.com");
 HttpsURLConnection conn = (HttpsURLConnection)
 url.openConnection(); URL url = new URL(“https://firebase.google.com”);
 HttpsURLConnection conn = (HttpsURLConnection)
 FirebasePerfUrlConnection.instrument(url.openConnection()); Decorator inside! @CodingDoug
  40. 61.

    How HTTP/S monitoring works buildscript {
 dependencies { classpath ‘com.google.firebase:firebase-plugins:1.1.5'

    }
 } apply plugin: 'com.google.firebase.firebase-perf' dependencies {
 compile ‘com.google.firebase:firebase-perf:15.2.0'
 } Uses the Transform API: goo.gl/PwBcLE @CodingDoug
  41. 62.
  42. 63.

    Firebase Remote Config • Use it to plan and stage

    rollouts of new features • Quickly back off the new feature if it has problems @CodingDoug
  43. 69.

    Firebase Remote Config • Find out what your users prefer

    by experimentation • Study the results in Google Analytics for Firebase @CodingDoug
  44. 70.
  45. 71.

    Firebase Remote Config (for perf) • Compare CDN/server performance •

    Compare cache configuration strategies @CodingDoug
  46. 72.

    final FirebaseRemoteConfig rc = FirebaseRemoteConfig.getInstance(); int cache_size = (int) rc.getLong("cache_size");

    // init cache with cache_size // later... Trace trace = FirebasePerformance.startTrace("my_trace"); Item item = cache.get("some_resource"); if (item != null) { trace.incrementMetric("cache_hit_size_" + cache_size); } else { trace.incrementMetric(“cache_miss_size_" + cache_size); } trace.stop(); @CodingDoug
  47. 73.

    Resources • Firebase home
 https://firebase.google.com/ • Slack
 https://firebase.community/ • YouTube


    http://youtube.com/firebase • Blog
 http://firebase.googleblog.com/ • Twitter
 https://twitter.com/Firebase