An Android device or emulator records detailed system logs, which can sometimes contain information which is pertinent to a test. Maybe our test failed and we want to see if our app logged an error to the system. Or maybe the only way to assert that our test succeeds is to make sure a particular pattern appears in the logs.
Android systems make these logs available using a tool called logcat, and Appium clients can access these logs remotely.
Both Appium and Selenium respond to the following JSON Wire Protocol endpoints:
Which can be called using the following methods in the Java client:
The Python client and WebdriverIO call the same methods this way:
The first method returns a collection of Strings which represent the logs which Appium provides. We are looking for "logcat" logs, but notice that Appium also provides android bug report data.
The logs are returned as a LogEntries class which implements the java.lang.Iterable interface. A single LogEntry object has toString() and toJson() methods, as well as some methods to get individual parts of the message such as timestamp or log level.
Something interesting to note is that every call to logs().get("logcat") will only return log entries since the last time logs().get("logcat") was called. The beginning of the system logs are only returned on the first call to logs().get("logcat"). The example code at the end of this post demonstrates this.
If we are running many tests over and over on the same device, it could be difficult to locate the point in the logs where our test ran (and maybe failed). If we wanted to address this, one strategy could be to call logs().get("logcat") at the beginning of each test. That way, when code inside the test gets logs, only logs which were recorded after the test started will be included.
There is also a desired capability we can set which clears the logcat logs at the start of a session.
The following example code shows how we can get the supported log types for our test session. Then we get all logcat logs, printing the first and last lines. We wait 5 seconds and then print the first ten lines returned again, demonstrating that instead of starting from the beginning of the system log, the second call resumes from where the first left off.
(All three versions of the full code demonstration are available on GitHub)