Firstly, apologies for the ridiculous title but I really could not come up with something more accurate.
I'm writing an app that interfaces with a particular type of network device. I can write instrumented tests that interact with said device just fine but those tests obviously only work if the device is accessible if the system running the tests are on the same network. Hence, using Firebase to run the tests is impossible because Firebase does not have access to the type of device the app interacts with.
However, it leads me back to a more generic question. How do you handle instrumented tests for functionality that is not publicly accessible? Be it special devices or networks, login credentials (hardcoding login credentials seem wrong), etc.
Is there any way to mock them? So say when you press a button you can mock a positive result?
Hope this made a sliver of sense.
Thanks
Sure, you can.
For example, mock framework - https://github.com/mockito/mockito
Related
Before i ask my question i will first explain some background information.
Our company is developing an app for iOS and Android. Our customers can decide to use our app (branded) or integrate our functionality into their app. As our app has some complex algorithms and communication protocols on-board. For this reason we want to provide a kind of SDK for our costumers who wants to integrate instead of using our app.
As we use BLE, NFC and GPS, we decided to make our own apps native. The issue is that many of our customers already have an app which will be a hybrid app in the most cases. So "just" making an SDK for all platforms is almost impossible, not only to build but even more to maintain.
Another important thing to keep in mind is that we want avoid that our customers need to understand our complete communication process, even stronger we won't give our algorithms or communication protocols to others because this is what makes our app/product unique at this moment.
So now the concrete question. Is it possible to provide our functionality as a kind of API so other apps can use the functionality of our app like a kind of API? This means that our app needs to be installed also on the end users smartphone but they don't need to use it individually. The idea is that the app of our customer communicates with our app like an API, our app does the communication with our hardware and gives back the result to the app of our customer. Note that user of the app should not see our app in foreground. (I have the idea from some games who requires "Play Games")
I know there is a way to exchange data between apps (Inter-App Communication) but can this also be used like kind of API?
Obviously this answer relates to Android only. (You may want to ask a separate question for IOS)
At its most basic, a Content Provider is used to exchange data. However, nothing prevents code being run in the provider host to extract that data.
For example, You can host a Content Provider in your app which when called with specific parameters, performs a number of your complex functions and returns a simple table of data (MatrixCursor) or even just a simple True/False response within that cursor.
You could further simplify the usage of this by creating an Android Library that your customers could import into their own project to make it more friendly and API like by adding methods and functions to the library that then delegated their calls to the Content Provider or even to a Broadcast receiver in your main app which could then respond with its own broadcast.
You could even make use of invisible Activities. i.e Call an activity in your app that has no UI.
Even more preferable would be to create your callable code as a self contained library that your customers could use which would negate the need to talk to separate apps completely.
In my understanding, you need other apps to invoke a particular functionality, say call a web API or open an activity and write something or open a popup dialog and do something.
In android: Yeh, it is possible by BroadcastReciever. you only have to listen to the particular action and perform the functionality.
So the task is, you only have to supply the action.
The app that I am working, is driven by Location Services. Driving with phone hooked to laptop is not always practical (and getting complex).
How would I write automated functional test for my app (googling shows UI related testing)? I understand that I need to inject values into following callback (since my app is driven by Location Manager)
#Override
public void onLocationChanged(Location location) {}
In a java application, I would create a unit that would have instance of my application and invoke the methods. But,
a) How would I do it for Android App (where there is no main method and everything is driven by onCreate())
b) How does it change, if above functionality is part of Android Service
Where we work, we use PowerMockito. I'm not a super fan of it, but I totally understand your frustration with unit tests. Here's a decent tutorial for the topic: http://www.johnmullins.co/blog/2015/02/15/beginners-guide-to-using-mockito-and-powermockito-to-unit-test-java/
Basically, what PowerMockito lets you do is write a bunch of Powermock unit tests. Those tests are going to let you mock the responses, and let you test your code. You can even manually call "onLocationChanged".
The reason I don't like PowerMockito is that that means you have to act like the Android OS. You can make dummy location responses and test to see if your code does the right thing, but it's much harder to test the code with field conditions. If a particular phone has an issue with the locations its returning, PowerMock is never going to help you catch it.
Use MockLocationProvider in android genymotion emulator.
See below link:-
https://mobiarch.wordpress.com/2012/07/17/testing-with-mock-location-data-in-android/
I am heavily testing my application with unit tests and Espresso tests. My next step is to make sure my application hits all required apis. For that reason I am looking for a way to write a test, which will verify the api calls.
I would really appreciate any suggestions.
What you are describing is called a "unit test". Unit tests are meant to test as many lines of code as possible regardless of UI.
Espresso tests are "instrumentation tests" (or "UI tests") intended to check if the app is responding to UI events correctly. They're not meant to verify the correctness of code, but the correctness of the functionality of the app as used by the user.
You can read about both at the official documentation. You'll find that unit tests are very different than instrumentation tests, and often harder to write because they require more engineering of your code to do correctly. You will likely have to "mock" the various parts of your application to make sure their APIs were called exactly as you expected.
There are 2 main goal when I was writing api tests:
First is component based. The goal was to make sure each class / component makes an api call when certain criteria is met (for example calling an api A when onDestroy() is called)
Second, is to make sure the Apis are called is certain order for the analytics purposes.
The first step I achieved by using unit tests with injected mock objects via Mockito and PowerMockito. PowerMockito was used primarily to mock static methods and to make sure the methods were called at least n times.
For the second step, UI test could be used, since it runs the real application. I have implemented the helper class, which was recording the instances when api requests were made. The script in Espresso was validating the order of api calls by referring the helper class.
When running android connected device tests, state that persists across application instances, such as permissions and files stored by the application, cause tests to interfere with each other.
For example, if I want to write a test for application behaviour when I deny runtime permissions and another test for application behaviour when I allow runtime permissions, then I must be very careful that the tests run in the correct order. If the allow test ran before the deny test, then the deny test would fail, because the permissions settings would already have been granted.
Another example, in a shopping app, the application may store the contents of the basket in the apps internal file storage to allow the basket to survive application termination and reboots. Testing the behaviour of the shopping basket then becomes very difficult, as the tests interfere with each other.
What is the solution to this problem?
Be sure to clean up the state after each test case. Tests which depend on the order run are considered a bad practice. In a lost of cases, you can implement a teardown() method (annotated with #AfterTest if you are using JUnit4) to do the clean up.
Create mock state objects during tests that can be injected into your app. I'm still new to this particular approach, so I don't have a lot of advice here. Some googling should help you get started.
Mocking the state / Injecting special state objects for the tests is a solution for most problems but not the Runtime permission case
I am developing an automated test suite to get the timing information for some Android applications (whose source code I do not have access to).
I haven't decided whether to use MonkeyRunner or Robotium yet. My main concern is after I perform an action on the UI (say typed an URL), how to determine when Android has fulfilled my request, all of the next activity's components are ready for use and I am ready to get the result and take the next action (say the page I requested is fully loaded, or email is fully opened).
For web-browser this is simple, I can just use onProgressChaged() or onPageFinished(). But I am looking for a more general way which works for all applications. I think Instrumentation.waitForIdleSync() or Instrumentation.waitForIdle() might be my best bet here.
However, as far as the documentation I read about MonkeyRunner and Robotium, none of them seem to integrate with waitForIdle well. In Robotium I could send some input and then get the output, but there doesn't seem to be a simple way for me to know when the output is ready, and maybe invoke a callback at that point. MonkeyRunner is similar in this aspect, too.
So I wonder is there a simple way for me to know what time my request has been fulfilled (as perceived by the user) without re-implementing Robotium functionality all by my own?
Thanks a lot.
This can be very tricky and entirely dependent on what exactly you asked monkeyrunner to do.
For example, if you have a monkeyrunner script, and issued a command to launch calculator app, you can have a python subprocess monitoring adb logcat -b events output to determine whether calculator app has been launched or not. If you are asking to press a button in the calculator, you can have a sleep of 1 or 2 seconds.
But there is no direct way to determine whether android has processed your event or not. Simply because, every operation differs and takes its own time.
You can put asserts in robotium and then use system.nanoseconds() before and after like a timer.
This might be a easy way to get timing information