Automate app local notification by manipulating the request and response - android

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;

Related

Is there better ways to intercept & modify network response in android?

When testing a app(without source code), I need to mock some response from 3party apis that I don't has access to yet.
My current way to do this is LSPosed + ssl unpinning module + fiddler's autoresponder.
But I can't make it work without a computer, which making test the app outside the office very inconvenient.
I'm about to make a module to hook some apis to do so, maybe a frida script?
But before I do this...
ANY suggestions ? or is there a easier way to forgery responses for some certain links?

How to test everything in Xamarin

So i've recently started using Xamarin.UITest in my mobile application. Its great for testing the UI, navigation etc. However im slightly confused as to how the best way is to test all the other parts of the app i.e the database, web connection, model and so on.
The project is cross-platform using a shared project.
Should these other tests be in along with the UITests or do they need their own separate project?
Furthermore in Xamarin Studio on OSX is there a way to test particularly the .Net only code without having to build and launch the whole iOS app?
Thanks
This question is really broad.
UI tests should only test the UI itself
Does navigation work correctly?
Is everything displayed like it should?
Are UI components visible, enabled, read-only etc.
Do components display correct data?
Your business logic should be tested in a unit test project
Do your classes process incoming data correctly?
Do they trigger the correct methods with the correct parameters in all cases?
Do they prepare the correct calls to webservices, databases or third party libraries? (You don't test the correct behaviour of other pieces of software here)
Do they throw exceptions as expected?
Unit tests are helping you the most to fix and avoid bugs. They are in general much more important for high quality code than all the other tests.
Integration tests are used to test the rest
Do databases, webservices, file system, operating system API work like expected?
Does it all work correctly together?
Does it all work fast enough?
There are many good books and links about good testing. It's way too much then to do it here.
Just a few examples:
http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/
https://developer.xamarin.com/guides/ios/deployment,_testing,_and_metrics/touch.unit/
http://blog.falafel.com/hold-right-learning-xamarin-unit-tests/
How to do integration testing in .NET with real files?
With these links, StackOverflow and Google you will find out that your unit tests should stay in a separate project. Mock your business logic as good as possible in your UI tests. So that they don't test all your code. Otherwise you will result in UI tests which often fail in order to changes inside your business logic. You would have to change the UI tests everytime you change the unit tests. That becomes annoying and frustrating quickly.
The main scenario that you're asking about is an integration test.
Since your tests drive the app from the UI layer, it's of course invoking all the code in the app and touching all the backend systems. But you're hoping to validate that the app and its supporting set of backend services all work correctly.
First of all, you'll need a way to expose data about your backend service to the test. You already did this, since the app probably uses a REST API and a database. For tests, you'd probably only want to do this for a staging or pre-production endpoint, somewhere that you won't be at risk for exposing real data by accident. You could configure a simple RESTful API that gives information about your backend services, and then invoke that from the test. You could also use backdoor methods which, in turn, call the API and prevent you from needing to make extra API calls from the test. Let's take a basic example, creating a new user.
Your test code might look something like this pseudocode:
var uniqueUser = Guid.NewGuid().ToString();
app.EnterText(firstName, "Test 1");
app.EnterText(lastName, uniqueUser);
app.Tap(createUserButton);
app.WaitForNoElement(e => e.Id("progress"));
app.WaitForElement(e => e.Text("User successfully created"));
// At this point, call your API using RestSharp or whatever makes sense for you
string endpoint = "https://my.server.net/user/getByLastName/" + uniqueUser;
var client = new RestClient(endpoint);
var result = ExecuteRequestHereAndItShouldReturnUserJSON();
Assert.IsTrue(result != null && result.FirstName == "Test 1");
That type of thing.
On teardown, you'd want to invoke a method to delete the test user by its id to avoid clogging up your database with test users created by the thousands of devices in Test Cloud. You could do this via backdoor or REST, whichever is safer depending on your current setup.
As for testing the code itself, just create a separate unit test project and use NUnit. There are a lot of great resources on testing listed in the other answer that can help you understand how to write good unit tests, when/how to use mocking, etc.

Android: Some questions about security and user authentication (register, login) through HTTP

I just can't get my head straight about this one. I'm currently building a rather large-scale application on Android. I've run in to a couple of problems regarding security and authentication though...
The Scenario:
I have an application that's making calls through HTTP (will implement SSL later) to a server running PHP and MySQL. Of course i want to use the existing user-database, so migration to another DB is not a solution..
I've managed to create the "register users via Android to the server"-functionality.
I've also made a working login, BUT this is where the problems start.
As users in the Android application I'am working on adds, edits, deletes and sync stuff on the server via/to the application, things get rather complicated. A little too complicated for me it seems :)
Problems:
As I get the result from my server-side login and pass it from the
server to Android via JSON, the connection dies and server-side I
'aint logged-on (sessions dies) whereas on the phone I'am. How can I
make the log-on persistent both on the server and in Android without
the need to log-on again? So that subsequent calls from Android to
the server is made with the same user, still authenticated. I.e. I
want sort of a one-time login ('till I logout) like in the
Spotify-app (and many others).
If I've understood things right, implementing SSL correct makes it
possible to send passwords in clear text to the server without the need to hash them first. Is this correct?
I just can't stop thinking about the fact that a MIM-attack would compromise any unique id I send from Android to the server. My first thought was to have the UID on the Android device as a "key" to the server after a successful log-on. But if that key gets in the wrong hands, the user associated with that UID will be compromised. I've looked at the AccountManager on Android but it seems rather over-kill in my case.
If someone could supply examples or at least guidelines, I'd be much grateful!
Thanks in advace!
ADDED SOLUTION DIAGRAM AFTER EDIT
Notice that this diagram shows the first start of the application. Later startups will NOT show the Login / Register form, but use the DUT instead.
// Alexander
Issue some form of a short-lived authentication token to Android apps. They would need to pass it in every request, and you will check it your Web app. Breaking the connection doesn't end the session, if it does, you have bug in your Web app: fix it. In Android, as long as you are using the same HttpClient instance, it will continue to use the same session, nothing special is needed.
Whatever you do, do not put off implementing SSL, do it now.

Faking HTTP request responses for testing in 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.

How to use mapserver on Android

Can I use mapserver on Android? I want to make a standalone application with implementing tiling, zoom and pan. I need to manipulate .map file dynamically everytime. Can anyone suggest me how to take approach or how to use php mapscript to invoke mapserver?
Mapserver is server side technology, it can be consumed by android or any other OS with a reasonable browser.
You need a server that will run Apache/Mapserver/PHP look at MS4w http://www.maptools.org/ms4w/
Second that, MapServer is the GIS server side technology for you to publish your data to services. You will be able to consume the service all cross platform (most of them) via OGC standard protocal(e.g. WMS, WFS)
To invoke the service from MapServer, is as same as other services using http request. More details about how to consume services from MapServer: http://mapserver.org/ogc/wms_client.html

Categories

Resources