This seems to be an issue with Android Studio inte...
# kotlintest
l
This seems to be an issue with Android Studio integration with JUnit... If you run via
./gradlew test
do all tests run?
d
I just tried, I get 1 test completed, 1 test failed and:
Copy code
.... > initializationError FAILED
    java.lang.reflect.InvocationTargetException
        Caused by: java.lang.NoClassDefFoundError at ....
But the class is in the module... 🤔
In the UI it just says no tests found though...
l
Are you using JUnit 5?
I believe that for Android you must use JUnit 4 for UI tests
It doesn't understand junit5 yet
d
I followed the instructions on Github...
l
I think we don't have explicit support for Android yet
And for that reason android support is not exactly documented
d
If you are using Gradle+Kotlin, this works for both Android and non-Android projects:
Kotlin (build.gradle.kts)
tasks.withType<Test> {
useJUnitPlatform()
}
dependencies {
testImplementation("io.kotlintestkotlintest runner junit53.3.0")
}
From the repo's readme
l
For
testImplementation
it works
It's different from
androidTestImplementation
d
That's what's failing...
l
testImplementation
is plain unit tests
You're saying that
testImplementation
is failing?
They're not UI tests
d
I get empty tests in Intellij (which I referred to as the UI -- to display test results), when I run them from the file tree, only when I run individual tests, it works...
I mean Android Studio in this case..
Could it be? Maybe because I'm using r8 and proguard to reduce the size of the debug apks, by minifying all the libs w/o the code...?
But the UI should really have reported that...
l
Ah, I see, I understood everything wrong
Hmm... If you run a single test it works in Android Studio, right?
The issue is running with more than one test
d
This is the error from Android Studio:
Copy code
Internal Error occurred.
java.util.NoSuchElementException
	at java.util.ArrayList$Itr.next(ArrayList.java:862)
	at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042)
	at com.intellij.junit5.JUnit5TestRunnerUtil.createSelector(JUnit5TestRunnerUtil.java:202)
	at com.intellij.junit5.JUnit5TestRunnerUtil.buildRequest(JUnit5TestRunnerUtil.java:82)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:55)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
And on the left side where the test results are normally shown, it says "No tests were found"
l
It seems that IntelliJ is trying to execute the way it know JUnit. If you try to run in the UI, but via Gradle, do things work?
d
From the gradle side-bar, it generates an html report that gives me the same
ClassNotFoundException
I got on the command line, with an initialization error.
l
Can you get me some more of the error from that ClassNotFound?
d
Copy code
Caused by: java.lang.ClassNotFoundException: net.bytebuddy.dynamic.MethodTransformer$Simple
	at <http://java.net|java.net>.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 29 more
And before that:
Copy code
Caused by: java.lang.NoClassDefFoundError: net/bytebuddy/dynamic/MethodTransformer$Simple
	at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:38)
	at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:72)
	at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:64)
	at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:27)
	at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
	at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:27)
	at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:32)
	at org.mockito.internal.MockitoCore.mock(MockitoCore.java:55)
	at org.mockito.Mockito.mock(Mockito.java:1449)
	at org.mockito.Mockito.mock(Mockito.java:1362)
But I have the Mockito dependency...
l
Hmmm
KotlinTest depends on Bytebuddy at some point
Perhaps they're conflicting
You can exclude Bytebuddy from KotlinTest
d
Actually, I used the newest version of KotlinTest, with an older one of Mockito (and I think also Mockk --- I don't really have the time to rewrite all those old tests...)
Ok, I'll try...
But if Mockito is older, wouldn't KotlinTest maybe count on some new features that won't exist?
l
I think the syntax is similar to this:
Copy code
androidTestImplementation("io.kotlintest:kotlintest-runner-junit4:3.4.2") { exclude(module = "objenesis") }
But if Mockito is older, wouldn't KotlinTest maybe count on some new features that won't exist?
I don't think so. We depend on that for very specific features, such as mocking
LocalDate.now()
I think the syntax is similar to this:
(This is actually a case where I had to exclude something for android, as Objenesis doesn't work with older androids)
d
Doesn't look like it ...
Copy code
testImplementation("io.kotlintest:kotlintest-runner-junit5:3.4.2") {
        exclude(module = "byte-buddy")
    }
Maybe I should add the group?
l
Can you see in the dependency tree if Kotlintest is still using it as a dependency?
d
Nope, it's not there anymore, so the exclude worked... but I have this:
Copy code
+--- org.mockito:mockito-core:1.10.19 -> 2.0.52-beta
|    +--- net.bytebuddy:byte-buddy:1.3.16 -> 1.9.3
|    \--- org.objenesis:objenesis:2.1 -> 2.6
(where Mockk is the one requiring 1.9.3), this could be my problem?
l
It could be possible
Anyway to update mockito to use the latest?
IDK if its latest version can use the latest bytebuddy
d
I'll try that now (hoping there weren't too many breaking changes...)
Seems like now on the command line my tests run, but in AS still no tests detected...
l
But still an exception?
Personally, I never run more than one test class through android studio, so I never faced that kind of issue
My guess is that it 'hardcodes' the JUnit execution
d
Not that one, only an NPE in certain tests...
So you mean just runs multiple tests from command line... 🤕
l
Personally, I don't run multiple tests
When developing a feature, I write tests for it
And then I go for a TDD approach • Write some of the feature • Write some of the tests • Repeat
When writing the tests, I execute that single class
d
But you don't run all your tests to see if there was a regression?
l
When I'm done with the feature I run all the tests from the command line just to see if I didn't by accident break something else
And for that I just go
./gradlew test
I don't run all my tests every time, just when I'm ready to deliver the feature
But that's me, there's no problem with running the tests more than once
I just say that I myself don't use that feature in Android Studio, so I don't even know how it works x=
d
... which is not as easy to see what failed, AS displays it so much nicer... I had to make major changes recently and was expecting things to "blow up", reading test results from the command line is a bit of a pain...
l
Maybe I'm just used to it tho. I never uses that display from AS, even when I was using Java + Junit hahah
When I'm making major changes, I make a chance in a class and then run that class tests
d
At some point in time it used to work even with KotlinTest... It seems to come and go...
l
And do that for every class
Do it seem to come and go in the same version?
Or you think that a new version broke that execution?
d
I guess it depends on the project. Truth is, I updated KotlinTest for running these tests, but I've had "come and go"s in the past too...
I think it only happens in certain situations, I don't think it's the version of KT...
l
I love android, but I hate android. Sometimes it can compile my code, sometimes it can't... and that's just because it doesn't want to anymore. Then restarting fixes everything
🤒 1
I think that the only way to fix that is to investigate JUnit's setup itself, I don't believe KotlinTest can do anything for it to work flawlessly everytime
@sam what do you think?
And by JUnit's setup I mean how Android Studio expects it to work
Perhaps improving our plugin and making this feature work better with it is a more feasible approach
d
I know you're not the only ones, a LONG time ago when I was working with Spek they had the same problems with their plugin... I don't know if they solved it...
s
This is the worlds longest thread, what is it you want me to think about @LeoColman
l
TLDR
Android Studio "Execute all tests" doesn't work flawlessly with KotlinTest
s
as part of 4.0 we're putting a big emphasis on android
l
But I don't think that matters. It seems that it's a problem with the tool and KotlinTest
We're putting an effort with tooling for android, and not exactly on how AndroidStudio works
s
No, we're going to do both
🎉 1
As part of the MPP work