Android - Unit testing with Robolectric is very slow - android

I'm using Robolectric 4.2 to write unit test cases for one of my Android applications. The test case is very simple like below:
#Before
public void setUp() {
landingActivity = Robolectric.setupActivity(LandingActivity.class);
}
#Test
public void shouldNotBeNull() {
assertNotNull(landingActivity);
}
But its taking forever to get completed. Can someone help me out what is happening and is there anything I'm missing.

Related

Tell Espresso to run specific tests on an emulator

I have Android instrumentation tests with Espresso. Some of my tests must be run on an emulator - due to using LinkedIn's TestButler (https://github.com/linkedin/test-butler) library. This library toggles wifi/gsm for specific test runs, and that is why these tests must be run on an emulator.
My question is - can I annotate any specific tests to run on an emulator, while having the other tests run on a real device?
Thanks
Yes, you can use a #ConditionalIgnore annotation as described in http://www.codeaffine.com/2013/11/18/a-junit-rule-to-conditionally-ignore-tests/.
You will have something like
public class SomeTest {
#Rule
public ConditionalIgnoreRule rule = new ConditionalIgnoreRule();
#Test
#ConditionalIgnore( condition = NotRunningOnEmulator.class )
public void testSomething() {
// ...
}
}
public class NotRunningOnEmulator implements IgnoreCondition {
public boolean isSatisfied() {
return !Build.PRODUCT.startsWith("sdk_google");
}
}
EDIT
For this specific case of detecting a device or emulator you can also use #RequiresDevice.
The most straightforward solution I found is to use JUnit Assume API: http://junit.org/junit4/javadoc/4.12/org/junit/Assume.html
So, inside the test methods that can only be run on an emulator, I put this code:
Assume.assumeTrue("This test must be run in an emulator!", Build.PRODUCT.startsWith("sdk_google"));
This results in the said test being ignored when it isn't run on an emulator, and a handy error msg in the run window:
As you can see, the other two tests passed fine (in the green), and the entire test suite was able to run.

Integration testing Android

I'm new to testing on Android. I see a lot of articles and tutorial about unit testing and with end-to-end testing (with espresso). It's ok. But what about integration testing ?
For the exemple, I use Firebase Database for my app. Is it possible to do this kind of test in the instrumentation test :
#Test
public void tryFirebaseTest() throws FieldRequiredException, InvalidPhoneException, InvalidEmailException, InterruptedException {
UserManager userManager = new UserManager(new FIRUserStorage(FirebaseDatabase.getInstance().getReference()));
userManager.createUser("test#test.com", "test", "+4778787", "", new CreateUserCallback() {
#Override
public void userCreated(User user) {
assertNotNull(user);
}
#Override
public void userExistError() {
fail();
}
#Override
public void userDatabaseError(String errorMessage) {
fail();
}
});
}
In this case, the test don't get in the callback.
For integration testing a Firebase app, you currently have two options:
Run local-firebase server, as discussed in this article, and write integration tests in jUnit/TestNG or whatever automation framework you like.
Write Espresso tests to test the complete integration
There are a few tools to help with the mocking like fingular, but you'll have to play with it a bit to see what kind of mileage you'll get out per your project and to what extent you integration test.

Android + JMockIt Integration

Has anyone successfully integrated JMockIt Unit tests while Mocking Android objects?
For example
If I do something like
#Test
public void contextTest(#Mocked Context context) {
...
}
Just by having the mocked context, it seems JMockIt causes a class rewrite error.
Would be great if someone has an example snippet showing everything is working fine.

Can you call getInstrumentation() from a test class in a referenced Android library?

I am working on implementing automated unit tests for our application. Want i need to do is be able to choose from a list of test cases and execute said test. My initial idea was to create (1) a standalone application that references a (2) testing library (android project with a bunch of unit tests) that would invoke the activities in our (3) application. So our application of course works fine and I don't want to make any changes there if possible. The standalone application would server as an interface to us developers for executing the tests. I want to be able to add more and more tests to the library. The issue I am having at this point is what follows.
In the library project I have a basic LoginTest activity.
public class LoginTest extends InstrumentationTestCase
{
... other class code
#Override
protected void setUp()
{
solo = new Solo(getInstrumentation());
}
}
My issue is the getInstrumentation() call always returns null. In my library manifest I have
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.matrix.edc.client.android" />
Make sure you have the robotium jar installed. The Solo class belongs to the robotium library.
If you have that installed and I've insulted your intelligence try changing your class declaration to
public class LoginTest extends ActivityInstrumentationTestCase2<YourMainActivity>
and change
solo = new Solo(getInstrumentation, getActivity());
in setUp().
You should also make sure, to call super.setUp() before any attempt of getting the instrumentation. I have not tested every subclass, but for ActivityInstrumentationTestCase2:
#Override
protected void setUp()
{
getInstrumentation(); // returns null
super.setUp()
getInstrumentation(); // returns valid instance
}
trying injecting the instrumentation in your setup, like so
public void setUp() throws Exception
{
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
solo = new Solo(getInstrumentation(), getActivity());
}

Android Junit Testing Freezes

I have an android app that I am unit testing. I have 4 test classes each with multiple test methods. I run them all at the same time from a test suite. I ran into a problem on the emulator where the test would just freeze in the middle of running the tests. I switched to using an actual device and the problem went away.
Fast forward a few weeks and I'm not having the same problem while running tests on my device. I have been on Google for the last couple days trying to find a solution but nothing I have found has helped.
The Issue
When I try to run all the tests the test will freeze eventually. And by freeze I mean the test itself freezes. I saw one solution that it might be the phone or eclipse. I restarted my phone, updated everything in eclipse including eclipse itself. I tried changing views to see if maybe the eclipse view was not refreshing but none of that helped. I also tried using the junit v4 library instead of v3.
If I run the test methods individually they all run and pass. Its only when I run them all from the test suite that they fail.
The Log
I checked the log and this is what I get:
03-13 12:11:04.526: I/TestRunner(23175): started: testCheckShowDialogEnabled(com.package.name.MainActivityTest)
after that there is nothing else in the log.
On The Device
The app is finished and is removed from the screen. It it not reopened again at the beginning of the next test.
The Code
Here is the code that I think might be relevant. If you need any more code just let me know.
public class AllTests extends TestSuite {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(MainActivityTest.class);
suite.addTestSuite(DatabaseHandlerTest.class);
suite.addTestSuite(ClassOneTest.class);
suite.addTestSuite(AnotherActivityTest.class);
return suite;
}
}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
public MainActivityTest() {
super("com.package.name", MainActivity.class);
}
#Override
public void setUp() throws Exception {
super.setUp();
mMainActivity = getActivity();
mSolo = new Solo(getInstrumentation(), mMainActivity);
}
#Override
protected void tearDown() throws Exception {
super.tearDown();
mMainActivity = null;
}
// all the test methods
}
All my test classes implement setup() and tearDown() similarly.
Anyone out there know why my tests keep freezing? Any help or suggestions are greatly appreciated.
#smk pointed me in the direction to find a solution to this. I just changed my tearDown() to this:
#Override
protected void tearDown() throws Exception {
mSolo.finishOpenActivities();
super.tearDown();
}
Now it works great!

Categories

Resources