I'm not sure this question belongs to SO since it is maybe to broad, but I don't know where to ask it (I did not find a better stackexchange site).
Context
I'm using UiAutomator to write some Ui test on android. I created some functions to simplify the write of the tests like the one in the doc
public void startMainActivityFromHomeScreen() {
/*Start the app from the home screen*/
}
As a developper, this works fine. But non technical peoples (contracting owner) can't easily use this functions to write tests.
Needs
I'm searching for a way for non technical users to write some scripts using the function I already defined. Here is a dummy example (both script format and actions)
Suite: Launch the app twice from the home screen
Case: Launch the app for the first time
Do startMainActivityFromHomeScreen
Expect ...
Case: Launch the app for the second time
Do startMainActivityFromHomeScreen
Expect ...
The important point here is to interact with java functions. I know other tools like calabash but it does not provide java interfaces.
Current approach
Here is an idea (nothing implemented)
Put all the functions in a lib
Write a groovy dsl (because groovy interact well with java) which allows non technical users to easily write scripts
Create a java program which will evaluate the groovy script and generate the android code source associated (with the lib (from (1)) as a gradle dependency).
Run gradle androidTestCompile
Since the functions are in a lib, developers can easily include and use it into their projects. So the same lib can be used for all users.
I hate this idea since I have to generate code source from my code, but this is the only one I have.
Questions
Is this approach as horrible as I think it is ?
Do you know another way to do it ?
I'd check out https://cucumber.io/docs/reference/jvm#java, it's a library that accomplishes pretty much exactly what you're looking for by letting you associate regex's with Java test methods.
Your Java code would look something like:
#When("^I open the app from the (main|home) screen$")
public void openApp(String launchScreen) {
...
}
And the testing file would look like:
Feature: Launching app
Scenario: Launching from first screen
When I open the app from the main screen
Then I see a blue icon...
Scenario: Launching from second screen
When I open the app from the second screen
Then I see a green icon...
Related
How do I combine a standalone Java application with an Android application?
I have a piece of code taken from the Google quick start examples that perform a task that I can't seem to be able to combine with my activity source code.
I'm of course talking about the following Google example: Sheet API, if I just add it as a standalone class and tell Android Studio to run this application, before my Android application, then it will produce what the code is suppose to do.
If I try to copy and paste the exact code into one of my activities it will give a couple of problems. One is that it can not find my keystore, another is a threading issue which I understand, another being that it can not find the credentials (even if the file is present), the newTrustedTransport-method call will be an issue, the setDataStoreFactory-method call will be an issue, file creation even with the correct uses-permissions and so on.
What is going on in the background that would make exactly the same source code work in one instance and not the other? What do I not know about Android Studio, and how an Android project works in the background for me having these issues?
I had an idea that I could just keep this standalone application as it is and store a file with the result that this Sheet example would provide me. But, since I do not have enough experience with Android Studio I have no idea if the result will be available for the actual Android application once it was made into a release. Will it? I can't save the output file generated by the Sheet example, under the res-folder, under the app module for some reason (scope?).
With other words... Can I have a standalone application, that is tasked to run before the Android application, to gather data and it will be doing this EACH time the Android application is run on a client? I feel like it would be stupid if the IDE would present this like this would actually work but then when the application is made into a release then the standalone application will not "follow" and be part of the release...
If I could just combine the source codes, I will not be having this issue at all. No examples online, neither Github or Youtube can provide me with answers on how to do this. Many examples online provide me with source code that is either out of date or just not what I'm looking for, and I really hate Google's way of explaining things. Just look at how they give code examples under this page: Google API Client Library for Java, and not give a full example where they would fit into the a project. Maybe all I need to make everything work is to use the code under "The library runs on Android 4.0 or higher (#Beta)."
I am wondering why they 'quick run/preview' displays object different that when you select 'main run' in Eclipse. I personally find that objects look better/neater/more elegant in quick run/preview mode than when I when I run and compile the application via the 'main run' option.
Can anyone tell me there is such a big difference, and what I need to do to actually make my application and its objects look like in 'quick run/preview' mode?
Quick run/preview in Eclipse is used to compile the code and run it more efficiently than normal run. I'm assuming you are referring to this when you are building GUI's?
Anyhow, quick run/preview is just to quickly preview your application regardless of the looks.
I'm assuming you want your GUI to have the Look and Feel of a Windows application rather than the "metal" Java GUI look.
This is done relatively easy as you can both make the "Look and Feel" of your application be based on whatever OS you are running or which one you prefer.
Refer to this simple article here.
Usually when I create something I have a number of different ideas on how to do it. Anytime I'm not sure which is better, rather than posting here each time, I'd like to test things myself. What methods can I use to test speed/performance/memory usage etc in Android?
While I personally have little experience with them, Performance Tips offered by the Android Documentation gives mention to two potentially useful programs for checking benchmarks.
Upon a cursory glance, it seems Traceview is useful for testing individual methods as well as broad scopes of an application.
Based on the documentation, creating a trace, retrieving it, and processing it can be done as follows:
First, find the locations where you want to test performance. Here's a quick sample:
public void doSomething() {
//maybe a long process that needs optimizing
}
protected void onCreate(Bundle savedInstanceState) {
// set up stuff
Debug.startMethodTracing("myfilename");
doSomething();
Debug.stopMethodTracing();
}
Second, retrieve the file from your Android device (note, you need a write-permission to create this file, so be sure to add that to your manifest). This can be done using the Android Debug Bridge (located in <Android SDK Home>/platform-tools). Open a command shell and run the following command
<Android SDK home>/platform-tools/adb pull /sdcard/myfilename.trace <Desired Location>
Lastly, you can process the output using Traceview with another command call. Traceview is located in the <Android SDK Home>/tools directory, so the call would look like this:
<Android SDK Home>/tools/traceview <Desired Location>/myfilename
Note that depending on your operating system, you may need to switch forward slashes with back slashes. This is a rough outline of the process outlined in the documentation (cited above), so I would recommend reading that before trying to implement this.
I'm working on a set of tests using UI Automator on Android. I have it working, but my current tests are made with lots of string literals.
The string literals were fine when I was just trying to get things to work in the first place, but they will be bad going forward. If the app is changed, the string literals will need to be changed to match. Also, it's stupid that my tests would have to be completely redone to test localized builds in other languages.
The app itself has all strings stored in resources. Every string has an invariant identifier... here's an example:
<string name="more_options">More options</string>
The app code will always use the name more_options to look up the string resource, rather than hard-coding "More options" into the code.
So what I want is to import all the string resources, store them in some kind of map object, and then in my UI Automator test code use something like m.get("more_options") rather than a literal string "More options" as I do now.
Whatever I do, I want it to just be part of the JAR file that gets built and pushed to the device to run the tests. I don't want to, for example, push the XML string resource files to the device and try to read them at test runtime. I want to have the data built in when the JAR file is built.
I looked at the files produced by building the app, and the names like more_options are just set to integers. These must be indexes or pointers into a store of resources, but I'm not sure how I could copy that store into my UI Automator project and get it connected up; in an Android app you use a Context object to access resources, and a UI Automator JAR file doesn't have a Context.
This has to be a common problem, and people must have solved it already, but my Google searches haven't found any discussions of how people are solving this.
If I don't get any advice, I'm going to write a Python script that imports the XML file and writes a Java file that has a function that builds the map I need, then call that from my UI Automator test programs. (I have a Python script that runs the sequence of command-line tools to kick of a UI Automator test, anyway... I don't mind making that do more work.) But I figure there should be a pure-Java solution for this, probably one that involves grabbing the already-compiled files out of the application's source directory.
You can get context:
val context = InstrumentationRegistry.getTargetContext()
and then in your tests:
context.getString(R.string.more_options)
I usually target a UI element through a resource ID. Those are pretty static. Am I missing something?
I was stuck up with a similar problem.
I ended up creating a static hash map in Java for all the string literals.
So I had files for different languages with the same key and their localized values.
Then wrote a module to manipulate the device language at runtime and return the corresponding localized value for a key.
I have written an android application. I would like to be able to customize the app programmatically. For example, change logos/titles within the application.
Assume I have a simple web server that displays a form with fields to input text, upload images etc. Upon submission of this form, I would like to generate an apk file available for download for the user.
Is there a way to script eclipse to achieve this? Is that even where I should be looking? If anyone has done something like this, (or have some ideas), please let me know!
Thanks
Is there a way to script eclipse to achieve this?
Possibly, but I doubt it.
Is that even where I should be looking?
Use Ant. Make a copy of some master project, make your adjustments from the entered data, and run the appropriate ant tasks (e.g., ant release build) to create the APK.
We have put together a system that creates multiple, customised APKs from a single body of source code. The system is not in a state where we can make it available (although we may open source it at some point) but the general structure is described here.
Having said that, the system you describe in your question is much more dynamic than what we need. We only need to create a few (~10) different variants. It strikes me that what you're trying to do would be better solved by having a single APK together with a configuration file. Your webserver would generate the configuration file, not the APK.