Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Testing Android applications Martin Konicek Software Engineer
 fb.me/martin.konicek1
 May 10, 2014

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Unit tests As a first line of defense ! ! ! ! ! $ buck test javatests/com/facebook/timeline/ PASS 10 Passed 0 Failed TimelineDbCacheTest PASS 16 Passed 0 Failed TimelineRamCacheTest
 PASS 4 Passed 0 Failed FetchTimelineHeaderMethodTest
 ...
 TESTS PASSED


Slide 6

Slide 6 text

Unit tests As a first line of defense ! ! ! Mocked: ▪ The OS ▪ Backend $ buck test javatests/com/facebook/timeline/ PASS 10 Passed 0 Failed TimelineDbCacheTest PASS 16 Passed 0 Failed TimelineRamCacheTest
 PASS 4 Passed 0 Failed FetchTimelineHeaderMethodTest
 ...
 TESTS PASSED


Slide 7

Slide 7 text

End-to-end testing

Slide 8

Slide 8 text

Instrumentation ! ▪ Toolkits: ▪ Robotium ▪ Espresso ▪ Test code runs on the device


Slide 9

Slide 9 text

Selendroid ! ▪ Embedded HTTP server running on the device ▪ JUnit test runs locally

Slide 10

Slide 10 text

! ! 
 public class AudiencePickerTest { ! private WebDriver driver; private Wait wait; private NewsFeed newsFeed; ! @Before public void login() { driver = DroidDriver.create(); wait = new DroidWait(mDriver, 20, TimeUnit.SECONDS); ! TestUser user = TestUser.create(); newsFeed = new Login(driver).as(user); }
 ! ! !

Slide 11

Slide 11 text

@Test public void changePrivacy() { AudiencePicker audiencePicker = newsFeed .goToStatusComposer() .openAudiencePicker(); ! assertEquals( "Default audience should be public", Audience.PUBLIC, audiencePicker.getSelectedAudience()); ! StatusComposer composer = audiencePicker .selectAudience(Audience.FRIENDS); composer.type("Droidcon Berlin is the best!").post(); ! // Fetch the story FeedStory story = wait.until(GraphQL.visibilityOfStory(user)); ! assertEquals( "Story audience should respect selection", Audience.FRIENDS, story.getAudience()); }


Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Fast feedback Before pushing to master

Slide 14

Slide 14 text

Performance testing

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Discovering hard-to-find regressions

Slide 18

Slide 18 text

Looking for glitches ! ▪ FPS ▪ Skipped frames (android.os.Choreographer) $ adb logcat 
 04-09 17:02:15.878 I/Choreographer(10122): Skipped 3 frames!
...
 04-09 17:02:17.109 I/Choreographer(10122): Skipped 2 frames! ...

Slide 19

Slide 19 text

Measuring memory, network, battery usage

Slide 20

Slide 20 text

Measuring memory, network, battery usage ! ▪ adb shell dumpsys ▪ reading system files using adb


Slide 21

Slide 21 text

Measuring time

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Measuring time Challenges
 
 

 The app provides timing information
 
 $ adb logcat | grep CommentsLoad ! D/fb4a:PerformanceLogger: Name: CommentsLoad; Timestamp: 9318686 D/fb4a:PerformanceLogger: Name: CommentsLoad; Timestamp: 9318722; Elapsed: 36
 ...

Slide 24

Slide 24 text

Measuring time Challenges $ adb logcat | grep CommentsLoad | grep Elapsed | awk -F';' '{print $3}'
 Elapsed: 46 Elapsed: 66 Elapsed: 76 Elapsed: 36 Elapsed: 40 Elapsed: 83 Elapsed: 34 Elapsed: 36 Elapsed: 33

Slide 25

Slide 25 text

Measuring time Challenges ▪ Garbage collection ▪ Thread scheduling
 
 ! ! ▪ Network ▪ Overhead of measuring code
 


Slide 26

Slide 26 text

Measuring time Challenges ▪ Garbage collection ▪ Thread scheduling
 
 ! ! ▪ Network ▪ Overhead of measuring code
 


Slide 27

Slide 27 text

@RunWith(PerformanceTestRunner.class) @TestRepetitions(50) public class CommentsLoadTest { ! ... ! @BeforeRepetition public void loginUser() { ...
 driver.disableNewsFeedAutoRefresh(); new Login(driver).as(user); } ! @Test public void openComments() { // Click the first "n comments" TextView in the News Feed WebElement feedbackTextView = wait.until( visibilityOfElement(By.id("feed_feedback_text"))); driver.gc(); feedbackTextView.click(); waitForMarkers("CommentsLoad", 5, TimeUnit.SECONDS); } ! @After public void goBackToNewsFeed() { driver.sendKeys(SelendroidKeys.BACK); } }

Slide 28

Slide 28 text

Time to load comments by device

Slide 29

Slide 29 text

Time to load comments by repetition Repetition

Slide 30

Slide 30 text

Profiling Traceview


Slide 31

Slide 31 text

Debugging allocations $ adb logcat
 
 ...
 05-08 06:13:49: D/dalvikvm(6759): GC_FOR_ALLOC freed 762K, 13% free 4116K/4688K, 
 paused 181ms, total 182ms !

Slide 32

Slide 32 text

Debugging Allocations Android Device Monitor


Slide 33

Slide 33 text

Debugging OOM Errors Eclipse Memory Analyzer


Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Questions