I'm new to Android development and just experimented with unit testing inside Android Studio. I have 2 questions,
each time I need to run tests I need to create a "Run/Debug Configurations" for the test class that derives from InstrumentationTestCase, and in this configuration I can only specify 1 test class and 1 test method at a time. Is there a way to break this limitation so I can run a bunch of test classes and their test methods altogether?
I have Log statements in my tests, but I could not find where it logged the output messages to, I checked logcat and event log but didn't find it there.
Thanks.
1) You should be able to right/control click either a test method, or a test class (suite) and run the test from the context menu.
After you run it once, the run config should be, permanently, in the list of runnable configurations, and available in all of the handy ways.
2) The most likely reason that your log messages are not showing up, is that Studio has this annoying habit of automatically installing a filter, on a run, so that it only shows log messages that are from the package of the app you are running. Since your test and your app are in different packages, it is probably filtering some of the messages away.
Related
I need to detect at runtime from the code if the application is run using an Instrumented Test. I'm looking for a solution that works without knowing the Test class.
You can read logcat logs in launcher activity of your application under test and find the instrumented test launch command in logs.
I am running JUnit tests as part of my Android app tests. In this case it's just testing the responses of an API we rely on that may be changed frequently (in order to validate later tests)
When these tests pass the output window of Android studio shows no messages. We'd instead like to start each method with a message saying which endpoint it is testing (E.g. "Tests /oranges//segments") so that the message always shows as the first message for both passing and failing tests.
I tried the android logs Log.println(Log.ASSERT, "...", "...") but that did not show in the android studio output.
Is there a way to do this? The output window I refer to is the one displayed below
(When a test is marked as ignored, you can supply a message to display. I'd just like the same behaviour for my other tests)
The old fashioned Java styled System.out.println(); will work.
JUnit tests are not executed on a Android device (or emulator) but on Java Virtual Machine on PC's environment. You have two solution:
Just use some Logger (like log4j, JDK logger, etc) or simply use System.out.
Use Roboletric and its capability to define shadow classes to redefine Log class.
I suggest you the second way. Roboletric already have a shadow class for log. To redirect output into console
#Before
public void setUp() throws Exception {
ShadowLog.stream = System.out;
//you other setup here
}
Some references:
https://guides.codepath.com/android/Unit-Testing-with-Robolectric
https://github.com/robolectric/robolectric-samples
http://www.vogella.com/tutorials/Robolectric/article.html
I hope it helps.
I am having trouble testing native applications (such as Contacts and Settings) using Cucumber-JVM for Android with JUnit. Initially, I got the following message:
"Test run failed: Permission Denial: starting instrumentation ComponentInfo???{com.test.contacts/android.test.InstrumentationTestRunner???} from pid=673, uid=673 not allowed because package com.test.contacts does not have a signature matching the target com.android.contacts"
To solve this problem, I signed the test application with the same keys of the Contacts native android application (shared.x509.pem and shared.pk8) and I also added the following line to the AndroidManifest.xml file (as suggested in How can I sign my application with the system signature key?):
“android:sharedUserId="android.uid.shared"
This seemed to solve the problem.
However, after this change, I only manage to run the first test from a test suite. When the second test is running, it gets lost in the getActivity() method from the class ActivityInstrumentationTestCase2, which my steps definitions class extends. More precisely, it doesn't get out of the mSync.wait() call in the method startActivitySync(Intent intent) from Instrumentation.java. The call to getActivity() calls launchActivityWithIntent(), from InstrumentationTestCase.java, which calls startActivitySync(Intent intent).
I found a similar issue on Why does getActivity() block during JUnit test when custom ImageView calls startAnimation(Animation)?, but the workaround described there doesn’t solve my problem.
My test application is really simple and it only checks the content of the buttons in the activity. I don’t have this problem if I use the same test application to test my own apps, only with native android applications such as Contacts and Settings.
Does anyone know something about this issue and could give me a light on how could I solve it?
Thanks in advance
I'm trying to debug an application that I'm writing using Android Studio but I can't seem to get any useful debugging information out of Android Studio's "Debug" view. I'm launching my application with the bug-looking "Debug" icon but the "Debug" view doesn't have anything useful (no stack frames from my application, for example):
Even if my application crashes I don't get any useful information. As I recall, the ADT plugin would automatically drop you on the line that caused the crash.
Do I need to do anything else to make my application "debuggable" in Android Studio? I've also tried forcing android:debuggable="true" in my AndroidManifest.xml but to no avail. Android Studio does seem to be attaching to the running process (the app shows the "attaching to debugger" message for a few seconds when it first launches).
There are some things to check:
If your app-debugger is working and stopping on normal breakpoints, maybe you have to set an exception-breakpoint:
Open Debugger
Press "View breakpoints"
Usually, there should be a breakpoint called "Any exception" with checkboxes on "Caught exception" and "Unchaught exception". If not, add an exception breakpoint yourself and specify the type(s) of exceptions you want the debugger to stop on (you can use wildcards in the exception-classnames, e.g. *Exception).
If your app-debugger is not working, check the following options:
Check if you have enabled USB-Debugging in the developer options of your device
Check if you have authorized the computer as a development machine in the developer options of the device (if unsure, clear the authorization-list from the developer options page and reconnect the device)
Check if your development machine has only one adb-server-process running in the background (if more, kill all of them with a process mananger and restart with "adb start-server")
Add "debuggable true" to your debug-buildType in build.gradle:
buildTypes {
debug {
debuggable true
}
...
}
If your app-debugger is still not working, restart your computer and re-install adb-drivers for your device. Make sure there are no conflicting drivers active with more than one connected device (maybe connecting only one at a time).
Note: even if you got exception breakpoints working, they might not be useful at all, depending on the type of the crash. Most of the times, you will get the debugger stopping in the Zygote-exception handler where you don't get much useful information or stacktrace.
In such cases, it is the easiest to just let the debugger resume or reproduce the crash without a debugger, and check the logcat-output for a stacktrace in the ERROR-loglevel of your app's logcat-output. Those stacktraces should have clickable line-infos thus enabling you to set a normal breakpoint on a relevant line of code in your app's source code to analyze the problem.
After updating Android studio this problem went away. Not sure what the issue was.
I'm doing UI test automation on Android using Appium and py.test. I'd like to be able to save a bug report using adb after a test fails.
Is there a way to tell if a test fails in my test code so I can then run save the bug report in the teardown?
Originally, I was just going to save the bug report after each test, but it's a bit excessive adding 45 seconds to each test.
You can implement a pytest_runtest_logreport hook in your conftest.py like this:
def pytest_runtest_logreport(report):
if report.when == 'call' and report.failed:
# save bug report
For more information, see Woking with plugins and conftest files.