android instrumentation testsuite - android

I have written two test cases in a package com.app.myapp.test
When I try to run them both of them are not getting executed, only one test case gets executed and stops.
I have written the following testsuite in the same package
AllTests.java
public class AllTests extends TestSuite {
public static Test suite() {
return new TestSuiteBuilder(AllTests.class).includePackages("./src/com.ni.mypaint.test","./src/com.ni.mpaint.test").build();
/* .includeAllPackagesUnderHere()
.build();*/
}
Is the code and location for this testsuite is correct?

Well, certainly leave off the '/src/' portion of the package listing for that invocation. Either way, the easiest and most flexible way to run your tests this is to make sure all your tests are in a subpackage of where AllTests is (e.g. com.app.myapp.test.tests) and use this for the suite:
public static Test suite() {
return new TestSuiteBuilder(AllTests.class)
.includeAllPackagesUnderHere().build();
}
Make sure your tests run individually, too, without the suite runner -- the suite won't pick up your tests if they're set up wrong to begin with.
(This is better than explicitly listing the package name since it's more portable -- you can rename your test package without breaking it, for example.)

Related

A bunch of unit tests fails because of an empty class

Recently I started to observe a very strange situation:
a whole bunch of unit tests (~160 different unit tests) fails because of one empty class in directory module-name/src/test/.
This class looks in the following way:
package com.myapp.android.common.extensions
class MyExtensionsTest {
}
When I remove this class, all unit tests pass. When I remove class declaration and leave only package in the file, all unit tests pass. But as soon as I add declaration
class MyExtensionsTest {
}
to the package, this makes ~160 different unit tests fail.
And the failing tests cover code of classes that seem to be not connected to the extension file MyExtensions at all.
And all these ~160 different unit tests fail
the same way if MyExtensionsTest class contains any test methods.
What can be a reason of this behaviour?
Is there anything wrong with my unit test setup?

How can I mock and test this class?

The follows was the code which I want to test.
public class Demo {
private static final List<Pair<String, String>> mList;
static {
mList = new ArrayList<>();
mList.add(new Pair<>("F0", "T1"));
mList.add(new Pair<>("F1", "T2"));
mList.add(new Pair<>("F2", "T3"));
}
public String getStr(int pos) {
return mList.get(pos).first;
}
}
I was an android developer. I have get some trouble in test and mock the code.I have use mockito.
I have try some code to test it,but the result was not my expect.
1.First try
#Test
public void test(){
Demo demo=new Demo();
assertEquals(demo.getStr(0),"F0");
/**
* java.lang.AssertionError:
* Expected :null
* Actual :F0
*/
}
2.Second try
#Test
public void test() {
Demo demo = mock(Demo.class);
doCallRealMethod().when(demo).getStr(0);
assertEquals(demo.getStr(0), "F0");
/**
* java.lang.AssertionError:
* Expected :null
* Actual :F0
*/
}
Anyone tell me how can I resolve this problem to make demo.getStr(0) == "F0" by call the real method? Thanks!
===========================
Another question relate to it
I have try an another test to test android.util.Pair class, and the result is that "pair.first" was null,.(There are androidTest and test directory,I put it into test package.Did it impact the result?)
import android.util.Pair;
import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.assertEquals;
public class DemoTest {
#Test
public void test1(){
Pair<String,String> pair=new Pair("First","Second");
assertEquals("First",pair.first);
//pair.first was null,why?
}
#Test
public void test2(){
Pair<String,String> pair= Mockito.spy(Pair.class);
assertEquals("First",pair.first);
//pair.first was null also,why?
}
}
Why the simple code is correct in real android environment,but failure in test?
I had the same problem too. month ago I have problem with TextUtils class too.
I report this to jUnit but they told me the problem is with android package because in unit test environment you don't have access to platform specific classes
for that pair case you can use this package. this works for me
import android.support.v4.util.Pair;
The problem in your first try is, that the public field "first" is actually null.
Is the Pair class the one from the "javafx.util" package or a custom implementation?
Did you forget "this.first = first" or something similar in the constructor of the "Pair" class?
I would also recommend to change the following line:
assertEquals(demo.getStr(0),"F0");
to
assertEquals("F0", demo.getStr(0));
so that the error is printed correctly.
Your second try does not make any sense. What is the point in mocking the class you want to test?
I think the second example has the same problem as the first one. Pair.first is never set. If you fix that, it should also work (untested).
From Google's Android tools website:
"Method ... not mocked."
The android.jar file that is used to run unit tests does not contain any actual code - that is provided by the Android system image on real devices. Instead, all methods throw exceptions (by default). This is to make sure your unit tests only test your code and do not depend on any particular behaviour of the Android platform (that you have not explicitly mocked e.g. using Mockito).
So how can we solve this?
In other words. If you need a default android class to work properly you either have to include it from a separate repository, or implement it yourself.
In the case of Android's Pair class. You can use android.support.v4.util.Pair instead.
To get access to this class, you can include com.android.support:support-compat:27.0.0 in your build.gradle or dependencies file.
If you are not using Gradle, you can copy the implementation of this file and use it in place of the official one. Or you can try and download the .jar file from this older version https://mvnrepository.com/artifact/com.google.android/support-v4/r7 (I have not tested whether it works)
Another approach (based on this) is to create the class in app/src/test/java/android/util/Pair.java and copy the code from the Android implementation.
This way you don't need extra dependencies. (There may be issues related to the implementation changing after you make the copy, but the dependencies may become stale as well.)

Android Instrumentation Test with PoweMockito

I need to mock a static method on an android instrumentation test.
If i need to mock a static method, the test class needs to be #RunWith(PowerMockRunner.class) . But my instrumentation test are required to run with AndroidJUnit4.class .
Is it possible to have two runnable? or is there any other way i can use power mock to mock static methods? or any other options to mock static classes?
To handle cases like this since version 1.4 it's possible to bootstrap PowerMock using a JUnit Rule instead of the runner. Something looking like this:
#RunWith(AndroidJUnit4.class)
#PrepareForTest(X.class);
public class MyTest {
#Rule
PowerMockRule rule = new PowerMockRule();
// Tests goes here
...
}
But be aware that PowerMock is using byte-code manipulation which someone needs to convert to dalvikVM dex. And currently there are no tools to support that (https://groups.google.com/forum/#!topic/powermock/9kwPaWoZ_14 , https://stackoverflow.com/a/27956309/624706)

AWS Device Farm Espresso tests order

I'm starting using Device Farm. My problem is that it is ignoring the order that I used to write tests. In local all works fine because Espresso executes tests in a certain order. To declare that order I used alphabetical order. All my classes starts with a letter (E.g. "A_EspressoTest") so I can choose which class has to be ran first.
Into my classes I use
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
to declare in which order my tests have to be ran.
It seems also like Device Farm ignores all my annotations (E.g. "#Test" ) because it is running also methods that doesn't have that annotation.
Lorenzo,
As of today, there is no way to specify the order of test execution with Espresso. Additionally, your observation about the #Test annotation is correct, we don't currently use that when discovering what test classes/test methods are selected.
AWS Device Farm currently discovers tests based on JUnit 3 style naming conventions (classes starting/ending with the word Test and methods within those classes starting with the word test.
For example:
// This class would be automatically discovered (by name).
public class LoginTests extends InstrumentationTestCase {
// This method would be automatically discovered (by name).
public void testLoginFormUsingInvalidCredentials() {
// ...
}
// This method would **not** be automatically discovered.
#Test
public void loginWithValidCredentials() {
// ...
}
}
// This class would **not** be automatically discovered.
public class Login extends InstrumentationTestCase {
// This method would **not** be automatically discovered since the class was not discovered.
public void testLoginFormWithValidCredentials() {
// ...
}
}
With all that said, we've heard plenty of feedback and requests for supporting test discovery using all JUnit 4 annotations and it's an area of improvement we're definitely taking a look at.
Hope that helps!
Best,
Andrew # AWS Device Farm

Possible to identify in setup which JUnit test case is being executed?

I have writing an Android JUnit test for an activity in my application. The Activity is modal, and can be configured via the launching intent.
I would like to write test methods to test the different modes. This would involve a setActivityIntent call in the setup method, configuring the Activity based on the test case we are running.
My question is, how can I determine which test case is about to be run from the setup method?
It turns out the answer to this question is very easy. junit.framework.TestCase has a getName method that returns the name of the current test case. Perfect.
In Junit 4.X, you can do the samething with TestName class:
public class MyTest {
#Rule public TestName name = new TestName();
#Before
public void before() {
System.out.println("running...", name.getMethodName());
}
}

Categories

Resources