Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Generated unit test source files not being picked up by Android Studio #229

Closed
muzzah opened this issue May 17, 2018 · 12 comments · Fixed by #234
Closed

[Android] Generated unit test source files not being picked up by Android Studio #229

muzzah opened this issue May 17, 2018 · 12 comments · Fixed by #234
Assignees

Comments

@muzzah
Copy link

muzzah commented May 17, 2018

Hi,

Im using the following setup
Android Studio 3.1.2
Android gradle plugin 3.1.2
Protobuf gradle plugin 0.8.5
Gradle 4.7

My protobuf configuration in my gradle file is as follows :

protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.0.0'
    }
    plugins {
        javalite {
            artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
        }
    }
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                remove java
            }
            task.plugins {
                javalite { }
            }
        }
    }
}

So all is pretty standard and up to date. Though when I add a proto file under [moduleDir]/src/test/proto directory, Android studio does not pick up the generated sources under the build directory and thus I cannot reference them. See the screen shot below :

screen shot 2018-05-17 at 15 36 49

You can see that the debug folder is picked up which is from a proto file in the main (debug) source set but the files under debugUnitTest are not marked as a generated source directory. I tried applying the idea plugin and adding that directory but did not work. Is this expected behaviour?

@muzzah
Copy link
Author

muzzah commented May 17, 2018

Just a small note here, if I add <sourceFolder url="file://$MODULE_DIR$/build/generated/source/proto/debugUnitTest/javalite" isTestSource="true" generated="true" /> to the .iml file in the module, and then tell Android studio to sync the file system, then Android Studio picks up the folder and I can make use of the generated sources in a unit test.

@muzzah
Copy link
Author

muzzah commented May 27, 2018

I take it this is expected behaviour?

@zpencer
Copy link
Contributor

zpencer commented May 30, 2018

This should work and sounds like a bug. I'll schedule some time soon to fix this.

@muzzah
Copy link
Author

muzzah commented May 31, 2018

I have done some more research into this as I wanted to provide a PR but I noticed a couple of things

The method addToIdeSources in Utils only adds the generated debugUnitTest folder if the idea plugin is applied otherwise the model is null and it does not add the directory as a source directory.

Also, even if I add the idea plugin to the project and the debugUnitTest generated sources are added to the ideaModel, I then refresh the gradle project in Android studio, the generated iml file still does not contain the sourcefolder line as mentioned above. I think this might be an Android Studio issue?

Its weird though that the main generated source directory is picked up without issue. Any idea on why the test generated source directory is not being picked up but the main generated source directory is?

@zpencer
Copy link
Contributor

zpencer commented May 31, 2018

Right, addToIdeaSources only ends up adding the sources if the idea plugin is available, because it is the idea plugin that generates the iml files. Android Studio is built on top of intellij so I think this behavior is fine.

What happens if you apply the idea plugin to your project's build.gradle, delete the iml file, and run ./gradlew idea? Does the generated iml file contain the debugUnitTest source set? I'm just wondering if Android studio does something different than just executing the idea task.

@muzzah
Copy link
Author

muzzah commented Jun 1, 2018

Yeah I tried doing that but it seems Android studio does not like that. It needs to generate the iml files itself by importing the project. I also tried adding an idea module definition in the build.gradle file to specify the directory to add as a testSourceDirectory but that also did not have an impact.

I do think Android studio is doing some magic in the background that is different from a standard IntelliJ build. Just out of curiosity, has this been working without issues in previous Android Studio builds?

Android Studio is built on top of intellij so I think this behavior is fine.

Im not sure this is the case nor do I think that Android Studio calls the idea plugin to generate the iml files. The reason I say this is because

  1. Modifying the Idea model in my own build file has no impact on the resulting iml files.
  2. The IdeaModel instance that is returned by project.getExtensions().findByType(IdeaModel) in the addToIdeSources method is always null unless I specifically apply the idea plugin when using Android Studio. But if from my own testing, if point 1 is true, then the protobuf plugin modiyfing the IdeaModel will have no effect either. Either that or AndroidStudio does some wacky things that wipes that info out.

Though I think the key here relates to the main generated sources. These are located under /build/generated/source/proto/debug/javalite and are detected by the IDE as generated sources. If I can figure out why that is being detected by Android Studio as a sources directory then maybe we can figure how to do the same for the test sources directory.

@zpencer
Copy link
Contributor

zpencer commented Jun 1, 2018 via email

@zpencer
Copy link
Contributor

zpencer commented Jun 1, 2018

This may be the correct way to add source folders to Android studio:
https://stackoverflow.com/questions/18947314/how-to-add-a-linked-source-folder-in-android-studio

If it works, then the protobuf plugin should be using the same way to set it up for the Android plugin, rather than idea plugin.

EDIT: this probably is not right, since the generated sources are not really the same as user created source sets.

@zpencer
Copy link
Contributor

zpencer commented Jun 1, 2018

I'd also like to confirm whether ./gradlew build works at all for you when you use protos added to local unit tests.

@muzzah
Copy link
Author

muzzah commented Jun 3, 2018

./gradlew build works without issues. I can also run ./gradlew testDebugUnitTest without issues from the command line too. I think its very specific to Android Studio. I noticed the patch you put up, let me know if you still need a simple project that has the problem and I can share one.

Also with the link you shared, adding

sourceSets {
        test.java.srcDirs += "$project.buildDir/generated/source/proto/debugUnitTest/javalite"
}

into my android block in the build.gradle file does indeed work and Android studio see the generated files as a test source directory.

@zpencer
Copy link
Contributor

zpencer commented Jun 4, 2018

Thanks for verifying. The reproduction test case is no longer needed.

Do you happen to know whether there's a gradle task that generates the Android studio .iml files? That would allow us to add a unit test. So far I have been validating the behavior by handl

@muzzah
Copy link
Author

muzzah commented Jun 8, 2018

Not that I am aware of but ill look into it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants