android testing mockup components - android

I would like to make some automatic UI tests for my Android application using recomended approach ( http://developer.android.com/tools/testing/index.html ). My activity fetches data from server and after getting response it modifies some UI elements. I want to check whether UI is modified properly but I also want to test this issue without connecting to server. I thought about providing mock component instead of object which connects to server on behalf of activity. But how could I in my test cases tell acivity to replace original object with mock object? Do you know any good approches?
I thought about putting a special flag in Intent using setActivityIntent (indicating that mock object should be used) before calling getActivity in my ActivityInstrumentationTestCase2 instance.
But this approach requires adding some if statements in application code what makes code less clear and more complicated.
Do you have any better suggestions? Thanks in advance.

Related

Sending data from an activity to an object on a 3rd party activity

In the course of creating an android library, I've learned I need to be able to open an activity from a generic library object and have the activity pass back data to the the library object. Normally, I would simply use startActivityForResult and call it a day, but in this case the library object will be using the client application's context. As such, any result would be sent to the client application and not to the library object.
So the flow would be something like this: Client instantiates our library object -> the library object determines it needs to present its own activity and does so -> library's activity returns data to the library object which can continue processing
I've tried a couple of different solutions but none seem to produce the desired results.
fragments - the issue I ran into here is that the fragment is tied to an activity which means it would need to somehow be tied to the client's activity in order for our object to get what it needs. So for our purposes this doesn't make sense to use.
Temporary splash screen - this is the route we're currently leaning towards since a basic splash screen would allow us to leverage our object on an activity we owned which could then call the activities it may need along the way and then return a response to the client's app in the activityForResult. The drawback of this design is that we were hoping to leverage a set of events which the client could code to when we fire them off. However this can be worked around if needed.
Also looked into leveraging the sharedPreferences but the issue there would be that when we returned to the client's activity we'd somehow need to "kick" the library to continue working. We don't want our clients to have to make multiple calls into our library. And spinning off a background thread to "poll" feels like very bad practice in this situation.
So what I'm looking for is whether the 2nd approach is really the only way to solve this or if there is another way in android development which I'm currently unaware of?

Functional tests in android. How to wait for fragment result?

I'm trying to add test to a quite big android project. So, I'm able to add the test, both to activity both to fragments, and get they run correctly.
But in my case, most of the fragments, when started, starts a Runnable into a new Thread. This thread connect to APIs, request and parse data, and return them to a handler, in the calling fragment.
The question is: How am I supposed to ask the test to wait until the data are retrieved by handler, so I can check them values?
How about instead of waiting for the values to return from real objects. You create mock objects that can return whatever value want instantly. Mockito is a great mocking framework that is very easy to use on Android.
http://code.google.com/p/mockito/
The way you go about using it is to create mock objects as opposed to real objects and you have to find "seams" to insert them into your tests. With a mock object, you can get it to return whatever value you want for any of its methods. With a mock object you can isolate dependencies. Therefore, in your example, you may want to create mock objects that mock the object that is connecting to the api because then you can return whatever value your tests need for the server to return to test whichever part of your app that you are testing. For example, if your testing whether the signUp activity is opened if the server returns that the user has entered a wrong password, you create a mock object that will return false to your activity and then insert that into where the real object is supposed to be.
Most people have issues testing existing code (that was not built with testability in mind) because there usually aren't any seams to insert test objects. Check out this awesome blog about how to make code more testable. It is contains really great advice.
http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-decided-to.html

Testing Strategy for Web Services based Android app

I have a web services based app i.e. each activity calls a particular web service and populate data into view. I haven't done any testing yet but I was in the process of switching to Volley and thought I might add some testing too.
I was wondering what testing strategies should be for such apps. I'm playing around with the gradle-android-test-plugin and although Robolectric doesn't play well with Volley yet, it should soon (I hope).
Anyways, so the structure I use for my app is this:
ObjectJacksonRequest class which get the data from the webservices and parses them into POJOs
RequestQueue standard volley request queue
BaseActivity the parent activity of all my app's activities which houses the RequestQueue object and other common stuff
Various Abstract activities which I use to separate the UI code from the network code. For example, the AbstractAppleActivity is extended by any activity that needs an apple. The abstract activity does things like check if the Apple is still in memory when returning, load new ones, set up adapters for list views, etc.
Here's the questions I currently have. I have some intuition on the answers should be but I'd like to hear from the community. I'm sure there are others questions too that people might have and we can add those to this list:
What's a good way to test the ObjectJacksonRequest object for the various web services ? Should I be writing a separate test for each web service that returns and object ?
Should I be testing network requests with the actual webservices or mock the responses ?
Should I be testing the BaseActivity and the abstract activities or the activities that extend it for it's functionality ?
What is the best way to test an activity that doesn't have any values inserted until the web request is completed ? For example, an activity that loads a list of apples.
What's a good way to test the ObjectJacksonRequest object for the various web services ? Should I be writing a separate test for each
web service that returns and object ?
If I am understanding it correctly you want to test the webservice backend. In that case I would write a test per call, or even multiple tests per call one testing each response senario.
Should I be testing network requests with the actual webservices or mock the responses ?
I would mock out the responses. It is my experience that if you test against a real webservice, you will get random fails because the connection was to slow or timed out or something and you end up running your test twice just to be sure it wasn't a random fail.
Should I be testing the BaseActivity and the abstract activities or the activities that extend it for it's functionality ?
I would not test the BaseActivities unless they have a lot of logic.
What is the best way to test an activity that doesn't have any values inserted until the web request is completed ? For example, an
activity that loads a list of apples.
Mock out the webservice response, so that it has values. You can do this with Robolectric. I believe the relevant method is Robolectric.addRequestInterceptor
I have more experience with testing now so here are my suggestions gathered for various sources:
- What's a good way to test the ObjectJacksonRequest object for the various web services ?
- Should I be writing a separate test for each web service that returns an object ?
- Should I be testing the BaseActivity and the abstract activities or the activities that extend it for it's functionality ?
All of these questions can be bundled into one. This is the question of testing inheritance hierarchies. The answer is, unfortunately, it depends. In most cases however, for abstract classes, testing the sub-classes will test the parent classes as well. Unless you have methods that have different use cases in different sub-classes, in that case you might want to test the abstract class so you can test all the cases as you code them (although if this is happening, you might be better off defining more objects).
- Should I be testing network requests with the actual webservices or mock the responses ?
This is an easy one. Always mock. As the other answer mentioned, you run the risk of writing flaky tests if you are using real webservices. Not to mention that testing the webservices is not your responsibility. You should only be testing code that you are responsible for.
- What is the best way to test an activity that doesn't have any values inserted until the web request is completed ? For example, an activity that loads a list of apples
This should follow from the mocked service. Once you have the mocked service. You can use it to send data to the activity in a reliable way and test the outcome.
Other Notes:
While the above are specific answers. In general I've found it useful to make some engineering decisions that facilitate not only testing but modularity of your apps. So these are some of my tips and to-donts from the engineering mistakes I had in my app design as per the question.
Use custom wrappers for services: In my question I am trying to move from Android's original HTTP to Volley. Part of the reason for these issues is that the app design couples the app with the networking library. One way to get around this is to use wrapper classes that are injected into your code. The underlying implementation of the wrapper class can then change without affecting the other source code. I have a blog post on this topic here.
Use Java modules: The Android gradle plugin in based on the gradle java plugin. You can therefore create Java library modules in your Android app project. I have found this is the best way to unit test your code that doesn't interact with Android API's. This is way easier and faster than both the Android test framework and Robolectric. I find that when I'm using a Java library module, my UI code becomes lighter because I'm trying to have as much work done in the Java module as possible.

Android Is using Application Class as a contoller OK?

I would like to have all my Activities (7 to 10 different screens) submit data to a "controller" (sorry if I'm miss using the term).
Inside said controller data would either be uploaded or saved to data for uploading when no internet.
The controller would do checks and processing such as:
Checking for valid session.
Attach other needed credentials before
upload etc.
Session/User data would be stored in a Shared Preferences file the controller has reference to.
My goal is to have Activities do nothing more than collect the data and call the appropriate method (with a data object) asynchronously. The controller would know how to process the data for uploading or saving in the database.
Would placing these methods in an extension of Application be a bad idea?
It was mentioned that depending on application size this is feasable, but there could be better solutions.
Depending on the size of your project, that would be a suitable idea. However, there are some other ways you should know before choosing the method you're actually implementing:
Using a ContentProvider for your data, an AccountAuthenticator and then sync to the server using an SyncAdapter. Advantages are a good abstraction, independence from activities and many built-in features (for example: Android executes your code without a big battery life impact). However, implementing all the stuff is quite much work at first. If you don't want to use the ContentProvider, the same technique works with a stub implementation as well, the same goes for the AccountAuthenticator.
Using a Service, probably IntentService, for your uploading needs. Advantage is that the Service has an independent lifecicle and thus is not directly related to your Activity; a Service can get restarted if it has been killed by the system. Still more work than just using some static methods.
Using a static method as you're proposing it (in your case, the Application object; not completely static, but compareable). Quite easy to implement, probably the best way if there are similar tasks in multiple activities; your AsyncTasks can send their result directly to the activitiy that started it. However not suitable for long-running tasks.
Implementing within the Activity; If code is only used once; listed for completeness only, not for your case. Basically the same as using a static method.
These are the ones that popped into my mind, there might be some others, too. Feel free to add/suggest additonal ones.

Why use a android service?

Im wondering what is the point of using a android service to do background work when you need to do a lot of things just to access any public methods or get a large chunk of data from a service such as a larger List object.
why not just use a simple POJO that does stuff in the background for you in a seperate thread if you like and gain access to its public methods without creating interfaces using AIDL, binding to a service etc etc?
seems soo much work needs to be done to access a method from a service class or is that really not the point of a service class in android?
i have developed a android service class that gets 100's of items in a xml structure from a web service who i then parse it into a POJO that is then stored in a List but i am having difficulty finding a way to send this List back to the activity that called this service.
i've read about using parcebales objects but that along with all the intent.putExtra have a size limitations so i may run into problems in the future.
i am thinking of ditching Android services and i have quickly found out why i dont like using them in the first place :(
a simple SomeBackgroundPojo backroundTask = new SomeBackgroundPojo(); backgroundTask.getData();
Seems soooo much easier than dealing with parcelables, serealizable objects, AIDL, binding etcc etc all just to achieve the two lines of code i just typed above :(
Nitpick: an object running a threaded background task ain't precisely what's usually meant by a plain old Java object.
If you don't care what happens to the work being done if its requesting Activity or Application is shut down, then by all means avoid services. One of the main points of Services is that they can stay alive when the user navigates away from an Activity: if you're only doing work to fill a UI ListView, by all means use e.g. an AsyncTask, as is discussed in this earlier question.

Categories

Resources