Android Robotium Test for Non activity class - android

Can anyone tell me how can I write Robotium tests for non activity classes?
I have seen lot of example for activity classes but not for non activity classes.
Is it possible?
Thank You.

Robotium is mostly useful for interacting with your app in a test case. These interactions are usually with activities.
If you want to test other classes, there's no need to use Robotium. You might look into Robolectric for running tests in the JVM on your computer.

Related

Is it possible to get rid of ActivityInstrumentationTestCase2 using Support Test Library?

I'm trying to use Android Support Test Library (previously android-test-kit) and create tests for one of my projects. It contains some 'functional' code along with UI code in single project.
My intention is to use JUnit4 and not mix with JUnit3, so I use AndroidJUnitRunner.
There's number of test classes created for the 'functional' code which follow JUnit4 and work fine.
Recently I've started to implement tests for UI components. Referring documentation receipt number of tests have been implemented. These activity tests follow JUnit4 style and extend ActivityInstrumentationTestCase2 based on above doc.
The problem that I'm facing now: it's not possible to execute all tests at once. If I try to run package / all tests (Activity and 'functional' are presented in the same project) from IntelliJ Idea - only pure JUnit4 tests get executed. I suspect that the problem is in ActivityInstrumentationTestCase2 which extends TestCase and is not pure JUnit4 test class.
Is it possible somehow to get rid of ActivityInstrumentationTestCase2 in Activity tests using Android Support Test Library (android-test-kit) and have all test running? Or my assumption about the issues rootcause (about TestCase) is wrong?
InstrumentationTestCase, ActivityTestCase and ActivityInstrumentationTestCase2 are deprecated, you should be using ActivityTestRule instead. InstrumentationRegistry is also useful to get a hold of application context and instrumentation instances.
Finally found only possible solution: copy InstrumentationTestCase, ActivityTestCase and ActivityInstrumentationTestCase2 into my project from AOSP source. After that, remove inheritance from InstrumentationTestCase of TestCase. Same way it's done in this project (AndroidJunit4).
There's actually no need for TestCase and these changes and documentation receipt are enough to have activity tests to be JUnit4 and avoid mixing issues.

Robotium with Mockito or Easy Mock

I'm new to Android testing and I`d really appreciate if some of you could help me with that.
I'm using robotium as automation testing framework (so far so good), but I have no idea how I use mockito or Easy Mock to add some mocks to my tests. I'm really stuck with that. Can someone give me some simple example on how to achieve this?
Thanks in advance
Short Answer/opinion
I don't recommend using Mockito for Android unit testing. The Android environment feels too complex to mock. The basic approach for Android unit tests is to run them within the emulator. Thus many of the container classes are already present and need not be mocked.
Long Answer
I also am relatively new to the world of Android unit testing. I have long written server-side unit tests and found Mockito to be one of the best tools around to simplify unit testing. Mockito is very helpful in mocking the behavior of complex objects. This helps to break any dependencies that your code-under-test may have on containers (e.g. servlet container or OSGI container), or on other complex collaborators (e.g. database connection classes).
This sort of mocking works well when your containers/collaborators have well-defined interfaces.
A couple months back, I decided to try Mockito with Android development. I found that Mockito does work if you have at least 1.9.5 and dexmaker. Dexmaker handles runtime byte-code generation for Android's Dalvik VM.
The first thing I tried in my very first test was to mock android.content.Context, and I found that is was HARD. First I tried to mock only the methods that I called directly, but then I found that these called into other methods which had dependencies on application resources, ... Eventually the mocking got so complicated that it defeated the purpose of using Mockito in the first place.
So I gave in and started using the Android unit test helper classes (AndroidTestCase, ActivityUnitTestCase, ...). I was discouraged that I now had to rely on the emulator which meant SLOW test execution. Perhaps Mockito still has a place in this type of test. It might be useful for mocking things like external data sources.
Anyways, this is just my 2 cents.

Mocking android applications like the contacts app using Mockito

I am trying to write functional tests for an android application. The problem is that most functional testing frameworks that I have explored (calabash-android, robotium) have a limitation on the number of activities from different applications that can be tested in the same test. So if in one workflow I need to select some contacts from the android contact picker I cant test that entire flow because the contact picker activity is part of the android contacts application and the framework can't test an activity from my application and the contacts application at the same time.
One possible solution my team thought of was to mock out the call to the contacts activity to return a dummy intent with contact information so that our application workflow can be tested. We are trying to use mockito to achieve this. However I am stuck pretty early on. Here is what I am trying to do
MyActivity mockActivity = mock(MyActivity.class);
when(mockActivity.startActivityForResult(<?>,anyInt())).thenReturn(fakeIntent);
I am not sure what to put in the first parameter in the second line. I have tried Intent.class and android.content.Intent.class however it throws a compile error. If anyone has worked with mocking activities using mockito, some help will be greatly appreciated.
P.S. - If I understand correctly mocking is used more in unit testing than functional testing. So these tests would be more of a hybrid. If anyone has a better suggestion on how to go about these functional tests on android I am all ears.
It's hard to answer this without knowing the signature of your startActivityForResult method, but the general idea is to use any(Xxx.class), where Xxx is the type of the parameter. So either
when(mockActivity.startActivityForResult(any(Xxx.class),anyInt())).thenReturn(fakeIntent);
or the (kind of equivalent)
doReturn(fakeIntent).when(mockActivity).startActivityForResult(any(Xxx.class),anyInt());
The issue is that you cannot really "mock" (actually "spy") on the activity you're testing since it is created out of your control by Android's instrumentation code. In a unit-test environment where you would have control, you could follow the mock(MyActivity.class) or spy(myActivityInstance) path (spy would actually be better because you could re-use most of the activity's original implementation), but here not.
The only solution I found for this dilemma was to move certain functionality out of the activity into utility classes, ideally utilizing roboguice for that (#ContextSingletons can be used to process activity results). Then, in your test project, you would create your own test guice injector, set that as base application injector before you call getActivity() for the first time and then let the activity work on your mocked utility class.
I outlined the complete process here.

jUnit testing Database operations

I'm developing an Android application with database storage.
I want to test some classes that I use to access database.
I've found ActivityInstrumentationTestCase2 to test Activities but I haven't found anything to test classes.
How can I do that? I haven't used jUnit before.
Thanks.
I always use AndroidTestCases when writing unit tests for the Android platform. They provide access to a Context instance (if required), but otherwise work like the standard JUnit test class. You may also need to look at AndroidTestRunner to test your classes. There are some good tutorials out there; now that you know what to look for, I'm sure you can find them. Happy hunting! :D

Using Android Test Framework

Android provides various packages for testing like
AndroidTestCase
ApplicationTestCase
InstrumentationTestCase
ActivityInstrumentationTestCase2 ActivityTestCase
I need to know how to decide which package is best suitable for testing my app. Some info is provided in this link
http://developer.android.com/reference/android/test/package-summary.html
But I need more clarity on this...
TestCase – Plain old JUnit test case. It can be extended to test utility classes that are not tied to the Android framework.
AndroidTestCase – It extends JUnit’s TestCase. It’s a lighter
testing class compared to
ActivityTestCase. It doesn’t need to
launch an activity to run it. Its
getContext() method allows you to get
an injected context if you need one.
Since you can get a context from this
class, you can inflate your UI objects
to test their behaviors.
ActivityInstrumentationTestCase2 – It’s the newer version of ActivityInstrumentationTestCase. ActivityInstrumentationTestCase is deprecated in Android SDK 1.5. It’s a heavier testing class compared to AndroidTestCase. It provides UI and functional testing for a single activity. You can get an injected activity that you are testing on by calling its getActivity() method. The activity being tested is launched and finished before and after each test.
ActivityUnitTestCase – It gives
the tested activity an isolated
environment. When using it to test an
activity, the activity is not attached
to the system. This gives you more
control over what kind of environment
that you want your activity to be
tested in.
ApplicationTestCase – It provides testing for Application classes. It can be used to test the life cycle of an application.
InstrumentationTestRunner – The runner that runs the Android test
cases.
I just found this..Hope this helps for others...If u want more details like when and how to use, see the APIDemos test application in the samples directory within android SDK.
Please see the class hierarchy graph drawn by myself using PowerPoint.
The accepted answer gives enough info in words. I just to make it clear using graph :)
For the InstrumentationTestCase #Zorb asked, it's parent class for ActivityTestCase among others. It enables you to call the getInstrumentation method to get an instance of instrumentation so that you can operate application, activity, and so on.
INTRO
To clarify your question and collocate the classes you are asking for, it is essential BEFORE to divide testing in two categories. JUnit tests (in theory plain Java) and Instrumentation tests (that also are part of the JUnit test package but allow you to test more SDK Android related functionalities).
Traditional JUnit tests isolate a section of code and run a test. Instrumentation tests access instead more inclusively the android components. BUT ALSO THE INSTRUMENTATION TESTS DERIVE FROM THE JUNIT PACKAGE although they are instantiated in the system even before any application code is run and this explain why are slower, furthermore they need an emulator or phone that run the app you are testing to be executed.
(Follow in Bold all the class you mention, but there are others even more used that I will write without without the bold character).
****FIRST PART**(Junit tests)**
A) Junit tests that extend TextCase (are usually faster than Instrumentation, and combine well with Mock framweworks)
AndroidTestCase: It allows to have access to the Context of the Activity you are testing and their resources, it is a base class that extends more specialized subclasses, it is ideal to access databases, filesystem data. You can easily call getContext() and access the Resources without establishing a direct contact with the Activities as will be with Instrumentation tests.
ApplicationTestCase that controls the environment where you text the application, mainly the context and the life cycle. Other really useful extensions of AndroidTestCase allow you to control Loaders,Services,and Content Providers, but for some reason still not any Broadcast receiver that you can call it [indirectly][1] with the method InstrumentationRegistry.getTargetContext() and then instantiating BroadCastReceiver. Also it is really common to use different Mock framework with Junit that is usually faster than InstrumentationTests
-.-.-.-.-.-.-.-.--
****SECOND PART**(Instrumentation tests)**
B) Instrumentation tests, that extend TestCase
Are considered functional tests, focused more to insure that they work well with the user side, the View part of MVC.They are usually slower than the other mentioned category
InstrumentationTestCase is a base class useful to send key events to UI to simulate QWERTY keyboard keys or DPAD buttons,also it launches the Activity that have to be tested, and even Intents
ActivityTestCase Usually is not used alone,it just has common code for the subclasses, but in the case you are not satisfied by the 3 classes that inherit from this one(see below) like a new future component you can use it by the time will not exist a TestCase class dedicated.
ActivityInstrumentationTestCase2 is the most used Instrumentation class to write functional tests, from the constructor is invoked the instance of the Activity to test. Basically you call the activity with getActivity() and you can pratically run any method of that Activity.
ActivityInstrumentationTestCase, is deprecated, and ActivityUnitTestCase that although is under the Instrumentation is more similar to an unit test
I found this tutorial from droidcon 09 to be really informative. Complete with downloadable working source code examples.
Edit: The link seems to be dead, as pointed out in comments.
It walks through creating a Celcius to Fahrenheit temperature converter test-first using ActivityInstrumentationTestCase2, TestCase and AndroidTestCase.

Categories

Resources