Android Studio : Cannot use class from src in Unit tests - android-studio

since the last Update (of Android Studio ? or Gradle ?) I cannot import code from prod in my tests classes.
A few months ago, the tests were working without any problems.
I can launch the tests, using gradle in command line, or using AndroidStudio test runner. And it work nice : it passes when the code is ok, it fails when there is a bug.
But the auto-completion isn't working, the class, methods ... are red.
I cannot click on an object to navigate to the declaration ... and so on.
And the AndroidStudio automatic quickfix is : "add dependency on module xxx"
which add a line in the gradle file :
implementation project(path: ':app')
I have the same problem on several project, with gradle 6.1.1 or 7.2.1
AndroidStudio version is :
Chipmunk, 2021.2.1 patch 1
built on May 18 2022
the unit test, in app/src/test/java/com/apackage/ASimpleTest.kt
package com.apackage
import org.junit.Test
import kotlin.test.assertEquals
class ASimpleTest {
#Test
fun aTest(){
val plop = AClass()
assertEquals(1, plop.aMethod())
}
}
the class in app/src/main/java/com/apackage/AClass.kt:
package com.apackage
class AClass {
fun aMethod() = 1
}
I have no problem calling a method in the same folder as the tests.
The problem is test/main folder calling src/main

Related

How do I troubleshoot the Groovy error "unable to resolve class spock.lang.Specification"?

I am using Ubuntu Linux 16, Gradle 2.10, Groovy 2.4.5, and Java Version 9. I'd like to remove Gradle if I don't need it. I am trying to run this program here from GitHub.
Here is the text of the code:
package timezra.groovy.trampoline_memoize
import spock.lang.Specification
class RecursiveMemoizationSpec extends Specification {
int count
def fib = { n ->
count++
if(n == 0) 0
else if(n == 1) 1
else fib.call(n-1) + fib.call(n-2)
}.memoize()
def "calls should be cached"() {
when:
def actual = fib 10
then:
actual == 55
count == 11
// count == 177 //unmemoized
}
}
When I run it with
groovy RecursiveMemoizationSpec.groovy
I get this error:
/groovy-trampoline-memoize-specs/src/test/groovy/timezra/groovy/trampoline_memoize/RecursiveMemoizationSpec.groovy:
3: unable to resolve class spock.lang.Specification # line 3, column
1. import spock.lang.Specification ^
1 error
This program was quoted on different websites. Those versions produce the same problem. I expected it to work without this error. How do I get the program above to work?
This is a very old project and it doesn't look like it's been touched in 7 years. You shouldn't discard gradle but learn how to use it. checking out the build file you can see that it add the Groovy(1.8.3) and spoc dependencies. Since this project doesn't have a gradle wrapper I would use sdkman to download and install gradle:
https://sdkman.io/install
Then I would just run gradle test from the root of the project.
Another issue you might run into is that you are running Java 9. Groovy 1.8.3, probably won't run on Java 9. I know that Groovy has been working on groovy 9+ compatibility, in the 2.5.x version, and will be adding more syntax support in 3.0. So you can either update the build file to use a never version of Groovy, or downgrade to Java 8. If you install sdkman, it also, gives you an easy way to manage, and switch Java version on the fly.
If you still really want to get rid of gradle then you'll have to use the Groovy #Grab annotations, which will pull in the dependencies similar to gradle:
http://docs.groovy-lang.org/latest/html/documentation/grape.html
But I would recommend that you get to know Gradle, because it is a powerful build system.

Android Studio 3.1.1 - unable to add module (import gradle project)

Android Studio 3.1.1. New module -> Import gradle project, after I select project to import and confirm, IDE crashes with exception:
Element: class org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl because: different providers: SingleRootFileViewProvider{myVirtualFile=file:///home/michal/AndroidStudioProjects/FirebaseJobTest/settings.gradle, content=VirtualFileContent{size=26}}(1416c50); SingleRootFileViewProvider{myVirtualFile=file:///home/michal/AndroidStudioProjects/FirebaseJobTest/settings.gradle, content=VirtualFileContent{size=26}}(665cfacf)
invalidated at: see attachment
com.intellij.psi.PsiInvalidElementAccessException: Element: class org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl because: different providers: SingleRootFileViewProvider{myVirtualFile=file:///home/michal/AndroidStudioProjects/FirebaseJobTest/settings.gradle, content=VirtualFileContent{size=26}}(1416c50); SingleRootFileViewProvider{myVirtualFile=file:///home/michal/AndroidStudioProjects/FirebaseJobTest/settings.gradle, content=VirtualFileContent{size=26}}(665cfacf)
invalidated at: see attachment
at com.intellij.psi.util.PsiUtilCore.ensureValid(PsiUtilCore.java:502)
Do you know any workaround?
I was facing the same issue, seems like IDE issue, try manually adding
include ':app', ':your_module_name'
in settings.gradle and sync gradle, hope it helps.

AndroidStudio 3.1.1 does not put kotlin classes on the classpath so you cannot run kotlin classes from the IDE

Below is how this issue manifests if you try to work in the kotlin REPL. However, you see the same issue more directly if you try to run a kotlin main fun from the IDE -- the kotlin classes are not on the classpath. Instead they are in .../app/build/tmp/kotlin-classes/debug. However, they do get put in the dex file.
I am looking at Kotlin for Android, and started with a very simple project (created freshly by Android Studio 3.1.1).
To learn kotlin I wanted to play with a simple .kt class converted from java.
After a rebuild, the Kotlin REPL is started, and this problem happens:
You’re running the REPL with outdated classes: Build module 'app' and restart
Welcome to Kotlin version 1.2.30 (JRE 1.8.0_152-release-1024-b01)
Type :help for help, :quit for quit
import hanafey.com.shoppy.Thing
val x = Thing("a", "b", "c", 1.0)
println(x)
error: unresolved reference: Thing
import hanafey.com.shoppy.Thing
In this case I ignored the "outdated classes" warning because it was not true.
So I believe the IDE and click the provided link to "Build module 'app' and restart". Now it claims another problem:
There were compilation errors in module app
Information:Kotlin: kotlinc-jvm 1.2.30 (JRE 1.8.0_152-release-1024-b01)
Information:4/14/18 7:49 AM - Compilation completed with 1 error and 0 warnings in 889ms
Error:Kotlin: Unsupported plugin option: org.jetbrains.kotlin.android:enabled=true
Am I wrong to think I should be able to fiddle with non-android related kotlin classes in the REPL?
When AS launches the kotlin REPL it includes the following directory in the classpath which contains the java files:
.../app/build/intermediates/classes/debug
However the kotlin classes are in:
.../app/build/tmp/kotlin-classes/debug
Either the gradle build is not putting the kotlin classes in with the java classes, or the kotlin repl is not started with all of the needed directories on the classpath.
If i understand correctly, the package hanafey.com.shoppy isn't included and therefore the unresolved reference.
:load /dir/path can be used to import all the packages in dir/path and the following should work.
val x = Thing("a", "b", "c", 1.0)

I have to restart IDE to run tests

Weird bug with Android Studio 2.2 when running a single test directly in IDE - I'll either have "No tests found" or run my previously compiled test.
Example:
#Test
fun testyTest() {
}
I'll create this test, and get the "No tests found". So I restart, and test is found! Obviously, the above test passes because it's empty. Next, I want my test to fail. So I manually throw an exception and add one line of code, below.
#Test
fun testyTest() {
throw RuntimeException()
}
Now I recompile, and this test passes too, because IntelliJ is for some reason has cached the previous test and reruns that. To get this test to properly fail - I must restart the IDE.
Anyone know what's going on? Note - I'm using Kotlin pretty heavily in this project.
EDIT 2: This is a JVM test (non-android, src/test/java) in an android library project.
EDIT: here's a full test class
package com.example.zak
import org.junit.Before
import org.junit.Test
class ExampleTest {
#Before
fun setUp() {
}
#Test
fun testyTest() {
//throw RuntimeException()
}
}
Found the fix...the issue only occurs when there's a variant selection conflict. Removing the conflict fixed the issue.
Check if you're have all these dependencies:
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
testCompile 'junit:junit:4.11'
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
}
Also as you're using Kotlin please disable entirely Instant Run in File -> Preferences.
EDIT: You're talking about tests in library - do modules and project has these dependencies and proper configuration.
It looks like after Gradle rebuilding, test works fine.
I found this bug description in the JetBrains IntelliJ bug tracking system. Here is the URL:
https://youtrack.jetbrains.com/issue/IDEA-149275
It discusses a change that was made to classloading that may impact Junit test execution. A workaround is suggested by adding a line to the options.xml config file. Here is an example workaround for Windows boxes - change as necessary for your platform. The version of Android below is the current 2.2 release:
1) exit Android studio
2) navigate to the config/options directory for your Android version:
e.g. C:\Users\YourNameHere\.AndroidStudio2.2\config\options
3) then add the "<property name="idea.dynamic.classpath.jar" value="false" />" line inside the component block of the options.xml file:
<component name="PropertiesComponent">
<property name="idea.dynamic.classpath.jar" value="false" />
Start Android Studio and try running local Junit tests.
I guess you use gradle in your project? I had the exact same problem and the solution was to use gradle to execute tests (inside the gradle task list) instead of using the menu (right click on the test file and run tests).

Android Studio Google Play Services no autocomplete

I use AS 0.4.2 then imported GMS as described in doc:
https://developer.android.com/google/play-services/setup.html
dependencies {
compile 'com.android.support:support-v4:19.0.0'
compile 'com.android.support:appcompat-v7:+'
compile 'com.android.support:support-v13:13.0.+'
compile 'com.google.android.gms:play-services:4.0.30' }
all what is detected by IDE is R class, but rest of code is invisible.
On the other hand I put following code:
import com.google.android.gms.common.GooglePlayServicesUtil;
(...)
private void connectGms(){
Log.d(MbcConstants.TAG,
"check for gms"+ GooglePlayServicesUtil.
isGooglePlayServicesAvailable(this));
}
And it works, but IDE still shows class name in red, but properly shows the params and returned type for method.
Ok - it seems like a bug in Android studio.
What I've done do fix it:
remove all dependencies (use F4 key) from project and the module
delete files from projectroot/.idea/libraries
open the module gradle.buld
add back all dependencies that are needed by your project to work. In my case:
dependencies {
compile 'com.android.support:support-v4:19.0.0'
compile 'com.android.support:appcompat-v7:19.0.0'
compile 'com.google.android.gms:play-services:4.0.30'
}
Synchronize gradle.build once again
Continue your adventure of love and hate or return to eclipse.
All you needed to do was hit the Sync Project with Gradle Files button after editing the build.gradle file by hand.

Resources