Faking HTTP request responses for testing in Android - android

I'm writing an Android app which sometimes needs to request data through HTTP from a REST API. I'm using the Apache DefaultHttpClient for performing requests. Is there a way to write tests for this app and "replace" DefaultHttpClient's response when running the tests so that test results are always consistent?
As an example of the things I'd like to test, one of the web services I'm accessing takes a string and performs a text search, returning a paged list of objects. I need to test the cases where the list is empty, the list fits in the first page, or the list is larger than a page and the app needs to make several requests to get the complete list.
I'm not the developer of this web API nor can modify its responses, so I can't change what it returns. For the above example, if I want to test the case where the list returned is empty, I could just search for a string which I'm sure won't return any results, but the other two cases are harder because what the service can return is always changing.
I think ideally I would have a way to get a modified DefaultHttpClient when running tests, that returns a hardcoded result for requests to a given URL instead of actually doing the network request. This way I would always get consistent results independently of the real web service's response.
I'm currently using Robotium for testing but I'm open to using other tools too.

Yes, you can definitely "fake" responses when using the HttpClient framework. It's quite convoluted, and I will have to leave most of the details up to you, but I will give you a quick overview:
Implement ClientHttpRequestFactory, mainly so you can override the createRequest() method so you can...
Return your custom implementation of ClientHttpRequest, in which you can override the execute() method so you can ...
Return your custom implementation of ClientHttpResponse in which you will finally be able to return your fake response data, e.g. getBody() can return the content of a file, you can hardcode the headers in getHeaders(), etc.
The rest is figuring out how to best tie all these shenanigans to your service layer.

You might give Charles a try for something like this. Sorta a non-code solution.
http://www.charlesproxy.com/
I use the Charles' reverse proxies and the map local tool for things like this.
What you do is point your request at your local box on the reverse proxy port. Charles in turn can be configured to provide a static hard-coded flat file but to your app it looks like a 100% genuine web service response.
There are lots of other cool things you can do with Charles - watch traffic from your android app to and from your server and breakpoints (which allows you to tweak requests and responses before they are sent and received). Definitely worth checking out.

Another option is to use Dependency Injection so that you can change the HttpClient when running the tests. Check out Guice if you are interested.

I'm guessing you are interested in writing functional tests using the standard Android Junit testing framework. So you could just implement the parts of the API you are using on your own webserver and point at that server when running your tests.
If you'd prefer your tests to be self-contained, you could implement an Http server that runs on the device. Examples of using the Http server available in the Android class library are here and here.

Related

Automate app local notification by manipulating the request and response

I am looking for ways to basically manipulate data that is shown in my app by intercepting the API calls it makes and then basically manipulate the data ( positive and negative scenarios) and then observe how my App behaves. I have been manually intercepting these calls and doing it in Charles Proxy tool but I want to get rid of it and looking for a way to do this through Automation. Set up my test data intercept the API calls through a proxy and then run my functional tests on the App. I am looking to do this for both Android and IPhone Apps.
Note: I have been using Appium for Automation.
Appium is a black-box test automation tool, it has no API to manipulate with application on server side. On Android, it allows you to start Activity/Fragment with pre-defined state, but it is not equal to what you are doing.
I think the right way here is to mock your server, there are multiple libraries, one example.
Then you can make a build for Android/iOS apps to use your mocked server instead of real server. In this case you will pre-define response instead of overriding it with proxy.
You can ask your developer to log the things you want to intercept or if they are already being intercepted in logs.You just need to collect the logs from ADB and use that in your appium code.
You can get the adb logs using :
List<LogEntry> logEntries = driver.manage().logs().get("logcat").getAll();
for(LogEntry entries:logEntries){
if(entries.getMessage().contains("*Things you need from logs*")){
entry= entries.getMessage();
}
}
return entry;

Using okhttp mock webserver in production

I've been using okhttp's mock web server (https://github.com/square/okhttp/tree/master/mockwebserver) in testing for quite a bit now and it works really well. From reading the documentation and browsing Google, it seems the library is really targeted for testing.
My question though is whether there is any reason why I couldn't use this in production code? I have an android app that I am working on that requires the need for a mock web server. I've integrated it and it is working fine but I am concerned whether there is something completely wrong with what I am doing.
Also, are there any security risks that I should be aware of when using mock web server in production?
Thanks!
The MockWebServer returns "mock" (in other words, "not real") data. If you used the class in production, you would have to either continue providing fake data to it, or make real HTTP calls through some separate library or tool and stuff its responses into the MockWebServer. And then, what would be the point? Why not just let OkHttp make the calls directly as it was designed?
My guess is you might be misunderstanding the relationship between OkHttp3 and MockWebServer.
OkHttp3 - HTTP client that makes HTTP requests over any HTTP stack (by default, uses the supplied Android device HTTP network; wi-fi, cell, etc.)
MockWebServer - only used in tests to supply hard-coded (not real) HTTP responses to an OkHttp HTTP client so that a live network connection is not needed during the tests, or to consistently simulate various network connection issues such as dropped connections, invalid HTTP responses, server errors, etc.
You should only be using OkHttp3 in your application code.
In your tests only, you have MockWebServer to fake responses (or intercept if you configure it that way) to test out your application's calls to OkHttp3. When you go to production, none of the MockWebServer code should ever be referenced or called (since you put it all in the test/androidTest source code directories, right?) and the OkHttp3 code would make real HTTP calls over the internet since MockWebServer won't be there to intercept them anymore.
Basically, if you have anything in your build.gradle other than testCompile 'com.squareup.okhttp3:mockwebserver:x.x.x' and/or androidTestCompile 'com.squareup.okhttp3:mockwebserver:x.x.x' than you're doing it wrong. The main, real, production application has no need for a mock web server since it will be making real calls over the internet to a real web server.

Android : what kind of server?

I'm developing an android app where I would like to fetch some data (mostly text) from the internet but not necesseraly from a website! I would like to have a server that allows clients to fetch some text data. What kind of server fits my goals the best? Http or maybe simply tcp? I don't know much about http so I don't know if it matches my goals and/or if it handles well a kind of text "database".
Edit:
A use case could be: people could write comments and send them to the server. Then clients could refresh their app by fetching new comments from the server. Therefore I'M asking what kind of server could best handle services and kind offre database if needed.
I like using NodeJS in combination with ExpressJS for such purposes. This combination allows you to easily work with HTTP/HTTTPS which is allowed by practically every firewall or proxy server. As of the latter reason I recommend you to use HTTP instead of an own protocol. Furhtermore, Java offers the HTTPURLConnection client which is very easy to use. Moreover, securing traffic with TLS (SSL) is very simple. In addition, NodeJS is resource efficient, runs on Windows, Linux and even on OS X.
For getting the text you can use HTTP GET request handled by the get() method of the Express instance.
This compact tutorial helped me to get familiar with Express on NodeJS.
Without knowing what your use-case is it's difficult to make a good recommendation.
With that said you may find something like https://parse.com/ suitable.
They provide an Android sdk and the 'getting started' tutorials will have you up and running in no time at all.

Test http post w/o a client?

I'm building a data management system. In the end it will be sending SQLite data via http post method to an instance. I will not be building this web datadase and it wont be ready for some time. However I would like to continue my production of the app and get the http post methods set up correctly.
Is there a way to test http methods without already having a receiving client already set up?
Maybe a public client exists for this purpose?
I want to continue production (and testing) to the point so that when the web database is finally built all I need to do is essentially plug in the new url in my code. Is there anyway I can do that?
Thanks
You can ask it google
Example Henry's HTTP Post Dumping Server.
Stub the posting class, implementing an interface. Use it directly, or use something like Guice to inject it.
You can always set up a dev DB service, and should, but a stub may be sufficient for most of your dev.

Android App Development and Web Server Interactions

I am just learning about Android Development so excuse me if this is a bit off in nature.
I am wanting to make an app that interacts with a Database from my website, in a sense the two things will be one feeding the other. So with that. I am trying to figure out whats the best way to interact with my server. I don't want an app thats an app in a browser like environment I want to dev a full app that works independently of the site only sharing the DB and like features. So what would be my best approach?
Is building the app so it can post/get to php files on the server interacting basically through JSON/XML my best and or safest bet or is there a better approach that connects the App to the servers Database that doesn't require me to open the database to any ip that makes a request.
Just looking for opinions and suggestions here. I figure everyone who's going to see this is familiar with Android development and best practices where as I could and have surfed blogs and all else but the opinion seems to be 50/50 as to which is best.
I'm sure there are libraries out there for Android that help you with HTTP Get and Post, however, if you really want to understand what is going there are just a couple of classes you have to understand in order to make the necessary classes yourself.
First, get to know HttpClient, HTTPGet, HTTPPost, and HTTPResponse. Some of the later versions of Android have some nice other classes as well, but those four is pretty much all you need to get started.
You need to do something like this:
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.myurl.com/api_name");
HttpResponse response = client.execute(request);
If you debug this (with a real URL of course), you'll notice that your app kind of freezes during client.execute(). This is the point at which the request has actually fired and the app is waiting for a response. Once you actually get the response, it isn't very difficult to get the data out of it.
Once you understand this, you'll want to get to know AsyncTask, which is endlessly useful for performing background tasks. You can find the documentation here: http://developer.android.com/reference/android/os/AsyncTask.html There is a great example of how to use this right at the top.
Using these two concepts together you can perform asynchronous HTTP requests. Basically, put your actual HTTP execute code in doInBackground of your AsyncTask. At the end of the doInBackground return your response, and then do what you want with your data in the AsyncTask's onPostExecute.
We've found that providing a proper RESTful web API that hits the database on the backend in whatever language you choose (be it PHP, RoR, whatever) provides a useful interface for any number of uses (your own website, mobile apps, etc).
Then it's a matter of your Android app interacting with the RESTful API, which is simply HTTP requests. Those can be encapsulated in helper classes to make them straightforward as well.
Based on my experience, the best framework for doing RESTFul things with Android is: Spring Android
From a client perspective, it provides all the tools needed to access secure RESTFul services. Since it is Spring, it provides nice abstractions over most of the boiler plate http code. As an example, it provides a clean way to perform a GET that returns json, and then serialize that to a POJO.
As an example:
RestTemplate restTemplate = new RestTemplate();
// Add Jackson JSON Message Converter to Template
restTemplate.setMessageConverters(
new ArrayList<HttpMessageConverter<?>>() {
{
add(new MappingJacksonHttpMessageConverter());
}
}
);
// Simple Conversion - pojo is now populated
MyPojo pojo = restTemplate.getForObject(url, MyPojo.class);
The approach you mention in the question: PHP on the server and JSON for requests/responses, does work. But getting it perfect can be tricky.
I found it helpful to have small request/reponse classes for each call on the Android side, like SaveNoteToServerRequest, SaveNoteToServerResponse classes which are just plain java objects with whatever fields are needed for the request/response. Then you can use a library like GSON to convert the request object to JSON and convert the http response from JSON to the response object.
On the PHP side you can create a small class for the response object, then json_encode at the end.
That way you're not directly manipulating JSON objects, just using your own plain java objects or php classes most of the time.
Hope that helps.

Categories

Resources