I am running test on multiple devices at once using the adb test command. My pseudo shell script looks like this:
for each device
adb -s ${device} shell am instrument -w -e ${classOrPkg} ${androidTestPackage}${test_name} ${main_package}.${flavor}.test/android.support.test.runner.AndroidJUnitRunner &
The problem is when a test fails, I have no information on which device the failure occurred. I could use LogCat but it requires looking up logcat for each device. And also, System.out.println() does not work.
One possible solution I am trying right now is by extending TestWatcher class and overriding the failed() method like this,
public class TestWatcherRule extends TestWatcher {
#Override
protected void failed(Throwable e, Description description) {
Description d = Description.createTestDescription(e.getClass(), "<<<< Failed on Device: " + Build.SERIAL);
super.failed(e, d);
}
}
Implementation:
#Rule
public TestWatcher testWatcher = new TestWatcherRule();
assertThat("My message", true, is(false));
I cannot get the device serial yet on the terminal.
My expected output would be something like this:
com.myapp.mobile.tests.BenefitCardDBTest:
Error in addDeleteCard(com.myapp.mobile.tests.BenefitCardDBTest):
**<<<< Failed on Device: HTC10xwrtxe**
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.myapp.mobile.qa:id/drawer_layout
Let's say this is my sample Espresso test:
#RunWith(AndroidJUnit4.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SettingsActivityTest {
#Rule
public ActivityTestRule<SettingsActivity> mRule = new ActivityTestRule<>(SettingsActivity.class);
#Test
public void checkIfToolbarIsProperlyDisplayed() throws InterruptedException {
onView(withText(R.string.action_settings)).check(matches(withParent(withId(R.id.toolbar))));
onView(withId(R.id.toolbar)).check(matches(isDisplayed()));
}
}
To run it on multiple devices I'm using Gradle's connectedAndroidTest which extends connectedCheck, so it :
will run on all connected devices in parallel.
From:
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Android-tasks
Just go use your terminal or console to go to your project's directory, then use:
./gradlew connectedAndroidTest.
This one is very useful as it would generate HTML test output which allows you to check which method on which device had failed.
It would look like this:
Hope it will help
Related
I am following the steps exactly as mentioned here to create instrumentation unit test cases. This is my Test class in the androidTest->Java->com.mypackage.name package
#RunWith(AndroidJUnit4.class)
#SmallTest
public class Test {
private List<String> list;
#Before
public void initList(){
list = new ArrayList<>();
}
#org.junit.Test
public void searchPlace() {
assert list.size() == 0;
}
}
But when I execute this test case, I get a message saying
Process finished with exit code 1
Class not found: "com.package.base.Test"Empty test suite.
Is there anything that I am doing wrong?
I've seen this error when the test instrumentation runner isn't set correctly. It should be set to android.support.test.runner.AndroidJUnitRunner in the build file. Also double-check the class package name is correct in the test configuration.
This happens if you Cut-Paste the test from Unit to Instrumental.
Simply goto Main menu -> Run -> Debug -> Edit config...
Delete old and broken tests.
And re-run.
I am having Xamarin.Android unit test project. I am executing test cases from adb command line as below.
adb shell am instrument -w -e class Package.Android.Test.MyTestClass
Package.Android.Test/app.tests.TestInstrumentation
I am having many test classes, every time all test cases are running from all the classes. I want to run test cases from specific class. Can anyone faced this issue.?
I tried seeing ADB log, it always prints "[Runner executing: Run Everything]
".
Test cases are written using NUnitlite.
You will want to use NUnit/NUnitlite Categories to restrict which tests are run.
In the default TestSuiteActivity the following call in the Activity's OnCreate sets which tests are run:
AndroidRunner.Runner.AddTestFilters (GetIncludedCategories (), GetExcludedCategories ());
Both, GetIncludedCategories and GetExcludedCategories in the default implementation return null, so you can subclass TestSuiteActivity, override these methods and return the Categories that should be run.
I currently do this and pass Categories to be run via extras (-e categories Large) added to the adb shell am instrument command.
Ref: TestSuiteActivity.cs
protected virtual IEnumerable <string> GetIncludedCategories ()
{
return null;
}
protected virtual IEnumerable <string> GetExcludedCategories ()
{
return null;
}
I have a simple test case where I'm trying to validate if a specific view is being loaded upon clicking on another view
public class SimpleActivityTest extends ActivityInstrumentationTestCase2<SimpleActivity> {
private SimpleActivity mActivity;
public SimpleActivityTest() {
super(SimpleActivity.class);
}
#Override
public void setUp() throws Exception {
super.setUp();
mActivity = getActivity();
}
#SmallTest
public void testBrushToolbar() {
View rootView = mActivity.getWindow().getDecorView();
View brush = mActivity.findViewById(R.id.brush1);
TouchUtils.clickView(this, brush);
ViewAsserts.assertOnScreen(rootView, mActivity.findViewById(R.id.container));
}
}
The above test fails when I use the Run option in Android Studio. Mainly because the TouchUtils.clickView() seems to not do anything at all and the new view is never loaded.
However, the same test passes when I use the Debug option even without setting any breakpoints!
I tried adding a Thread.sleep() and then running the test but even that didn't help. Any idea as to why this might be happening?
PS: I'm running on Android Studio 1.3.1
Update: The test fails even when I run from the command line using
$ gradle installDebug installDebugAndroidTest && adb shell am instrument -w -e class com.mypackage.test.SimpleActivityTest#testBrushToolbar com.mypackage.test/android.test.InstrumentationTestRunner
When creating a new project in Android Studio, I notice that it automatically creates an /androidTest directory under /src, where there is "ApplicationTest.java" class with the following code:
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
I'm guessing this is what Google wants us to use, but after searching for hours, I couldn't figure out how to use this class that was generated for me. Google's official doc seems to only list how to run on Eclipse IDE (not Android Studio), and I couldn't find any code that would let me perform a simple test (say like assertEquals(1,2)). Can someone show me how to write a simple test code using the above default template, and steps on how to run it, preferably from the command line?
EDIT:
I was able to write a simple test that is intended to fail.
ApplicationTest.java in /androidTest/java/path/to/package/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
#Override
protected void setUp() throws Exception {
createApplication();
}
#SmallTest
public void testMultiply() {
assertEquals("This should not pass ", 50, 49);
}
}
I am able to run this from Android Studio, but I just cannot figure out how to run that from the command line. Any help?
As Jared already said, this is an example setup for an instrumentation test.
I guess, you've already taken a look on this: Testing Fundamentals
Simpliest way to run these tests in android studio is to right click the class and click run.
It is also possible to add tests in your run/debug configurations.
UPDATE:
To run the instrumentation tests on command line, use ./gradlew assembleAndroidTest. This command will run all tests in your src/androidTest (instrumentation test) folder.
As njzk2 mentioned, there also is a ./gradlew assembleTest command. This command is for running all unit tests (which should be placed in the src/test folder). For more information about unit testing in android take a look on this: Android Unit Testing Support
EXAMPLE:
Here an example for an instrumentaion test in android:
#Override
public void setUp() throws Exception {
super.setUp();
InputStream is = getContext().getAssets().open("test.xml");
XmlParser parser = new XmlParser(getContext());
parser.parse(is);
...
}
#MediumTest
public void testSomething() throws Exception {
// test some data your parser extracted from the xml file
...
}
As you can see, i need the context for creating the input stream, therefor i have to go for an instrumentation test. The #MediumTest signals e.g. i'm accessing files from storage (see Test Annotations).
I followed this tutorial to achieve unit testing for my android app:
http://confluence.jetbrains.com/display/IntelliJIDEA/Creating+Unit+Tests
So i made a Android test module and i have the following testclass:
package test.app.com;
import android.test.ActivityInstrumentationTestCase2;
import junit.framework.Assert;
/**
* This is a simple framework for a test of an Application. See
* {#link android.test.ApplicationTestCase ApplicationTestCase} for more information on
* how to write and extend Application tests.
* <p/>
* To run this test, you can type:
* adb shell am instrument -w \
* -e class test.app.com.LoginActivityTest \
* test.app.com.tests/android.test.InstrumentationTestRunner
*/
public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {
public LoginActivityTest() {
super("test.app.com", LoginActivity.class);
}
public void testName() throws Exception {
LoginActivity activity = getActivity();
int num = 10;
int result = activity.test(num);
Assert.assertEquals(num*2,result);
}
Edit Configuration settings:
Class: test.app.com.LoginActivityTest
method: testname
Project structure:
Dependencies:
MyApp->Provided.
However, if i try to run the test i get the following error:
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES
A popup "Empty test suite" appears obove the run button.
The message is: Unable to attach test reporter to test framework or test framework quit unexpectedly.
Additional info:
I'm using git for version control.
I can't try using the emulator because even after a half hour, it's still loading.
Can you guys help me solve this issue?
I tried uninstalling the app from my device, but that didn't solve the issue.
Thanks!