I need some advices and guidance related to TDD of android applications
I'm developing a complex android application (an automated robo player for a web game). Now i have a pilot for it, and before start continue with it's development, i want to make full TDD for it.
The main purpose of this application is run as a background service that communicates with a http server - it will send http requests with json content
It has to 2 modes of running:
- service mode - it will run in background- read some data configuration from database and communicate with the server
- GUI mode - communication with server on demand + configuration for running in service mode.
GUI layer is designed as MVP, so all business done in a module (a MVP unit) is separated from view, therefore, all app logic is "NON android dependent".
I have several big layers that i need to make unit tests for:
- domain data access :
database storage (ormlite)
android specific storage - shared prefs..,
files
- server communication - http client (spring android rest template)
http content conversion (gson)
- background services - android services
- GUI - activities
- app business - android independent - algorithms, computations, ...
In conclusion will need TDD - for every of these layers individually, but also integration tests for a complete flow.
tests included :
- database DAO tests
- http client requests
- GSON conversion TDDs
- business logic - simple tests for methods
- unit testsfor running and scheduled background services
- activity unit testing
- test suites (service + DAO + json conversion + http requests)
My first question is what TDD frameworks would be best for my needs? Should i use mocking or not ?
Please give me some directions to go for. Thanks
At first, for automatic testing : junit.
For fluent assertions, you could look at fest-assertions. They provides a lot of examples, here. But enjoy this one on the String :
assertThat("Frodo").startsWith("Fro").endsWith("do").hasSize(5);
It isn't just harmonious, it increase also your productivity.
Since you want to write unit tests, you will have to write mock objects. Of course, you can do it without any framework, but it is very tedious.
Personnaly, i am big fan of Mockito. It's api is great and very fluent. Besides, you could the use the BDDMockito static methods to write test in a BDD manner. Look :
//given
given(seller.askForBread()).willReturn(new Bread());
//when
Goods goods = shop.buyBread();
//then
assertThat(goods, containBread());
Sometimes you will depend on class that you can't mock, for example a final class like BluetoothAdapter. In these cases (and only in these), you could use PowerMock.
Look also at this stuff :
https://stackoverflow.com/questions/2336488/resources-for-tdd-on-android
[Why Android isn’t ready for TDD, and how I tried anyway](
http://daverog.wordpress.com/2009/12/14/why-android-isnt-ready-for-tdd-and-how-i-tried-anyway/)
Introduction to Android Testin
There is also a book : Android Application Testing Guide
Since you mentioned integration tests, you might also be interested in RoboGherk as an automated acceptance testing framework for Android that was recently announced by my friend at LeanDog.
Related
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;
I am trying to create the bare minimum of a chatbot with dialogflow in an Android app. Initially I do not need the bot to hook into things or have context and entities. I just want it to match questions with answers as good as it can.
I do not come from the web world so this https://dialogflow.com/docs/getting-started/basic-fulfillment-conversation confuses me. The final part of the tutorial is not finished and it leaves me hanging a bit.
As an Android dev I want the app to:
call a rest api with the user text
or possibly:
invoke an SDK and have a local pretrained agent and not involve the internet an all
You can download the Agent but that is just some json files. I found an Dialogflow.SDK but it seems to be related to speech. In the dialog flow console you can 'copy curl':
curl 'https://api.dialogflow.com/v1/query?v=20170712&query=Hi&lang=en&sessionId=xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' -H 'Authorization:Bearer xxxxxxxxxxxxxxxxxxxxxxxxx'
I want to access the agent like that from multiple instances of an app.
Do you always need a 'fulfillment'?
The guide mentions creating folders on your local machine(in conjunction with fulfillment) are these only used to do a 'deploy' from your local machine to configure the web hook in the cloud? Or are they also used to deploy the entire Agent to the cloud project? (which i can't seem to find any instructions for, unless it's the same as for webhooks?)
gcloud beta functions deploy weatherWebhook --stage-bucket [BUCKET_NAME] --trigger-http
I have read questions with both tags DialogFlow and Android but most of them seem to involve Google Android Assistent which I have no interest in.
You do not need fulfillment. This is primarily for Dialogflow to take advanced actions or to use more complicated logic to handle the response.
You also cannot run Dialogflow processing on your device - all operations take place in the cloud. So you don't need to download the zip file unless you want to make a backup copy of your agent.
The REST interface you're looking for is the one you found. It handles more than speech - the /query endpoint can take a query parameter which contains "Natural language text to be processed."
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.
Here is one design/ best practices question..
I'm new to android development, and basically new to web/mobile solutions.
So, my question is - what are best practices when organizing structure of android application that get data from the remote server?
Should request to server go into one class that does communication with server (get and post requests), or should I look at my requests as data source, meaning that every data class manages it for itself?
or should I have more levels of abstraction - one level for acquiring data, other for model that uses some interfaces without knowing from what source data come from?
I'm curious how experienced android developers approach to these design issues...
Virgil Dobjanschi presentation is a good resource as pointed earlier, which basically tells you to run your requests from a background service so the activity does not get destroyed and to store your data in the database as early as possible.
For more technical details, the way I am doing it is to divide the app into three components:
1- Library to encapsulate the handling of the HTTP request and response (with ApacheHTTP), which can handle simple request/response and advanced features that might involve cookies (can be necessary for login) and modifying the HTTP header.
2- Marshal/Unmarsha layer, where I parse the server data (e.g. XML or JSON) and convert it to objects (i.e. models) that the rest of my app will deal with.
3- Persistence layer.
As per Dobjanschi's presentation, I usually make data requests run in a service not in a thread worker inside the activity.
Use one of the 3 models presented at this Google I/O talk. It provides you suggestions that will help you out on the whole process of definition of your app architecture. It'll also prevent you from making common mistakes beginners use to make:
http://www.youtube.com/watch?v=xHXn3Kg2IQE
This post will also help you out:
Need sample Android REST Client project which implements Virgil Dobjanschi REST implementation pattern
This is not really a problem, more like a general X vs. Y question.
So I'm experimenting with c2dm on android using a server written in google app engine. At the moment I'm using the "App Engine Connected Android Project" as a template with some added code myself. So the generated code use RequestFactory for a bunch of stuff, like registering/unregistering devices, sending messages, etc.
My previous experiences with backend communication has existed of setting up a connection to a servlet, writing to it (json) and reading the response (json).
So here's the question:
What are the benefits (if any) with using the RequestFactory for communication with the app engine instead of just writing/reading from an URLConnection's input/outputstreams?
Or is it really just a matter of taste?
One disadvantage of request factory is that it is very slow in retrieving objects.. A custom servlet and http request are MUCH faster(10x-20x faster!).
Check out this post for more details RequestFactory slow on Android
I haven't used it myself yet, but the main benefit, as I understand it, is that it makes it really easy to authenticate against the App Engine app with your Android credentials. Doing that by hand is a bit of a pain.