Android test raw resource - android

I have the following folder structure in Android Studio:
├── androidTest
│   ├── java
│   └── res
│   └── raw
│   └── test_file
└── main
├── java
└── res
└── raw
   └── app_file
I'm trying to access the test_file resource which exists in the raw folder of the androidTest elements. Here's the code inside a Robotium test case that inherits from ActivityInstrumentationTestCase2:
InputStream is = this.getInstrumentation()
.getContext()
.getResources()
.openRawResource(R.raw.test_file);
Android Studio throws a reference error since the resource cannot be found. The exact error is "Cannot resolve symbol test_file".
How can I reference this resource form a test case, which exists on the androidTest resources bundle?

By default your androidTest project will include your app's R class, but androidTest's resources will be generated into a separate file. Make sure you import the R class from your test project:
import com.your.package.test.R;
[..]
getInstrumentation().getContext().getResources().openRawResource(R.raw.test_file);
You can also directly reference the test project's R class:
getInstrumentation().getContext().getResources().openRawResource(com.your.package.test.R.raw.test_file);

I had the androidTest resources in the right spot (src/androidTest/res) and I still couldn't access them via <normal.package>.test.R. I spent a lot of time googling trying to figure out what was going on..
I FINALLY stumbled onto the answer. If you're building a buildType where you specified an applicationIdSuffix, your files are at <applicationId><applicationIdSuffix>.test.R !!!!
i.e.
applicationId "com.example.my.app"
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
if you have androidTest resources in the right directory, then you can only access them via com.example.my.app.debug.test.R !!!!

See Android Unit Tests Requiring Context. For instrumentation test use InstrumentationRegistry.getInstrumentation().getTargetContext() (in Kotlin: getInstrumentation().targetContext). Then you can access resources. You won't need to import R file.

As the others have stated, androidTest resource ids are generated in <applicationId>.test.R by default. Since applicationId can be modified by different build types and flavors, this leads to different R files location for each of them. This can be changed by assigning explicit value to testApplicationId in the defaultConfig of the app's android configuration in build.gradle. It can be useful if there are more than one build types/flavors that alter the appId, but the tests can be run for any of them.
build.gradle (app):
android {
defaultConfig {
applicationId "com.example.hello"
testApplicationId = "com.example.hello.test"
}
}
Test files:
import com.example.hello.test.R

Related

SqlDelight: "No table found with name"

I am having trouble with what seems like to be with the SqlDelight intellij plugin. I am trying to write the migrations in one place and not use CREATE statements at all inside the .sq files.
This is my setup:
src/main/sqldelight:
├── com
│   └── wtf
│   └── errorrepro
│   └── database
│   └── one.sq
├── migration
│   └── v1.sqm
└── schema
v1.sqm
CREATE TABLE something(
id INTEGER
);
one.sq
Here is the issue I am getting inside the editor. No code table-related code hinting is available here, generate menu is also blank in this file.
what:
SELECT * FROM something;
^^^^^^^^^
No table found with name something
build.gradle
I am only showing here the relevant sqldelight config, I am using version 1.5.3 (gradle plugin, intellij plugin and dependency are all on the same version).
...
sqldelight {
MyDatabase {
packageName = "com.wtf.errorrepro.database"
deriveSchemaFromMigrations = true
verifyMigrations = true
}
}
...
If I run any of the gradle commands, like generateDebugMyDatabaseInterface, the proper queries are generated. So I do not understand why the editor shows the 'No table found with name' error.
I have reinstalled the plugin, updated gradle, did a clean rebuild, invalidated sources ... Nothing seems to solve this.
Edit:
It is even weirder that in case I create a totally separate project Kotlin + Groovy Gradle and set up SqlDelight there, then the code navigation works well. It is only if I create this setup in an Android project (it can be entirely new) when the navigation fails.

Why resource naming convention was changed in Android?

In past when building multi language apps in Android I used to place strings.xml in following tree:
res
├── values
│   └── strings.xml
└── values-es
└── strings.xml
Currently (according to tutorial) it should rather look like this:
res
├── values
│   └── strings.xml
└── values-b+es
└── strings.xml
Please note values-b+es instead of values-es. I couldn't find why it was changed and to me it looks worse than previously, so I wonder what is the reason of such change?
What's more freshly updated Android Studio still auto-generates those names in old way:
I couldn't find why it was changed
The old approach still works and is what most developers use, because that is the one that has decent documentation. Also, the new approach only works on certain API levels (due to the poor documentation, I forget when it was added).
I wonder what is the reason of such change?
AFAIK, the new approach employs a different naming scheme, which extends support to more language/region combinations.

Adding layout resources to androidTest

I would like to add layout xml files into my androidTest folder to be used only for testing.
I added res/layout folder to androidTest and tried to add a layout file to it. But it gives error URI is not registered for xmlns:android="http://schemas.android.com/apk/res/android"
Somehow the project does not recognize it as valid layout file.
It is tricky to add xml resources to androidTest.
Android Instrumentation tests create another APK to run the tests against your original application. Although you can access your Context and objects from your main application, you cannot modify the generated APK file of your app.
That means you cannot put additional layout xml to your original application from tests that are in the androidTest folder.
Solution:
Alternatively,
you can create a buildType called espresso.
Then, create an espresso folder where you can put any java or Android resource you want to add.
You can even modify your AndroidManifest there.
Then, use testBuildType 'espresso'
Your build.gradle should look like this:
android {
testBuildType 'espresso'
buildTypes {
espresso.initWith(buildTypes.release)
}
}
dependencies {
espressoCompile 'somedependency' // you can even have special dependencies
}
When you run your espresso tests around that flavor, you will have an access to additional layout xml files you added.
Should look like this:
That's easy! In general, you should just put your resources under the src/androidTest/res folder. And that is! Then you can use it in your src/androidTest/java files. Yes, you can't use test layouts in your production APK, but you can use your test layouts in your test APK.
There're some problems that might confuse you. For instance autocompletion works well not so very often, but, anyway, it builds and works.
Recently I wrote custom control for masked EditText so I don't want to put any activity into the library, but I do want to have an activity to check the view and I do want inflate it from XML. You can see the whole code on the github page, here're some key moments:
$ tree androidTest/
androidTest/
├── AndroidManifest.xml
├── java
│   └── ru
│   └── egslava
│   └── lib_phone
│   ├── MainActivityTest.java
│   ├── TestActivity.java
│   └── actions
│   ├── HintViewAction.java
│   ├── KeepHintViewAction.java
│   └── SetTextViewAction.java
└── res
├── layout
│   └── activity_main.xml
└── values
└── styles.xml
So you can see, that under androidTest there's some kind of a separate project with its own manifest that registers Activity and so on :-) I would share more files, but it's just a project, no more and you always can look up the link.
The only thing that I'd like to warn you, that you should be ready that Android Studio will show you that your project contains errors even if that's not true :-) Good luck!
Cannot comment, but wanted to further add to #Slava's answer. If someone can add it as a comment, by all means.
Try suppressing the lint errors with the accepted answer from this question.
Android Studio Remove lint error

fastlane/supply dynamic what's new (changelogs)

fastlane supply android metadata has the following structure:
└── fastlane
└── metadata
└── android
├── en-US
│ └── changelogs
│ ├── 100000.txt
│ └── 100100.txt
└── fr-FR
└── changelogs
└── 100100.txt
Production builds and versions is changed some times before release so I had to change files names in changelog directories after every build.
I want to have only one "what's new" (changelog) file per locale for the latest build. Something like whats_new.txt
Does fastlane or supply provide such a feature?
supply is not set up to support such a strategy right now, sorry. I think it is a reasonable feature request though. Please submit an issue in our GitHub repository if it's something you'd like to see be possible!
A plugin like changelog might be what you are after. It allows you to pull from one changelog file like so:
read_changelog(
changelog_path: './custom_folder/CHANGELOG.md', # Specify path to CHANGELOG.md
section_identifier: '[Unreleased]', # Specify what section to read
excluded_markdown_elements: '["###"]' # Specify which markdown elements should be excluded
)
I do not, however, see builtin support for a per-locale changelog. For reference, the release_notes.txt file and/or function provide the functionality you describe when using fastlane for iOS projects.
I think what you want it's supported nowadays with the default.txt file
https://docs.fastlane.tools/actions/supply/#changelogs-whats-new

How to build multiple APKs from a single source project

I wanna get multiple APKs from a single source project.
Just the application's title, icon, and package name are different with the others.
The project is on gradle(1.12), as below.
.
└── my_project
├── build.gradle
├── settings.gradle
└── module
├── build.gradle
└── src
How can I do that?
You can use productFlavors for that, and the under the promo and full folders (for example) create strings file (promo/res/values/strings.xml) with the update title value, same approach goes for the icon.
productFlavors {
promo {
packageName "com.woony.promo"
versionCode 1
versionName "v1.0.0_promo"
}
full {
packageName "com.woony"
versionCode 1
versionName "v1.0.0"
}
}
The updated project structure should be like the following
.
└── my_project
├── build.gradle
├── settings.gradle
└── module
├── build.gradle
└── src
├── main
├── promo
└── full
And to generate the release apks just call the following once (just make sure you added signingConfigs and linked it in your release buildTypes)
gradle assembleRelease
All the common files like java code, manifest and base resources are under "src/main"
Move your applications specific folders into "src/projects"
declare two productFlavor (one per applications) specifying applicationId and versionName
create two sourceSet (one per project) indicating the specific res, java, etc.. folders (i just needed res folder)
Full project's structure
Now, use Build Variants (bottom-left of Android Studio) to select the application to run

Categories

Resources