This message was deleted.
# community-support
s
This message was deleted.
s
This creates the sourceset, but its not a test one, so I can't access test deps
I've tried copy pasting many things online and they all don't work, most don't compile
I tried creating a separate module, but I cannot get the dependencies to work on that either
Any help is much appreciated.
s
Would you mind giving me a quick rundown of what's happening in this snippet? 🙂
The above snippet doesn't work for me
Copy code
Could not resolve project :.
Required by:
    project :integration
t
Copy code
val functionalTestSourceSet = sourceSets.create("functionalTest") {
  compileClasspath += main.output + configurations["testRuntimeClasspath"] + commonTest.output
  runtimeClasspath += output + compileClasspath
}
Create the new source set. Set its compile classpath to the output of the main source set (i.e., the compiled class files), and set its runtime classpath to the compile classpath + the result of compiling this source set
Copy code
val functionalTestImplementation = configurations
  .getByName("functionalTestImplementation")
  .extendsFrom(configurations.getByName("testImplementation"))
the new configuration should extend from the default
testImplementation
configuration, mostly for ergonomics so I don't have to re-declare a bunch of test dependencies. This is optional.
Copy code
val compileFunctionalTestKotlin = tasks.named("compileFunctionalTestKotlin")
tasks.named<AbstractCompile>("compileFunctionalTestGroovy") {
  dependsOn(compileFunctionalTestKotlin)
  classpath += files(compileFunctionalTestKotlin.get().outputs.files)
}
Optional, this lets me write code in Kotlin and then have Groovy code depend on it
the most important block is the first one
e
if you're on a new enough gradle, use https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html to set up extra test suites
s
It's creating the source set but it's not a test source set
I'll try that
@ephemient Can I remove `
Copy code
tasks.withType<Test> {
   useJUnitPlatform()
}
with this plugin?
e
yes, replacing it with configuration inside the
testing
block
t
It's creating the source set but it's not a test source set
You are misunderstanding.
integration
is a source set. You don't need another source set (named "test") inside of it
put your code in that source set and add test-related dependencies to it, and you're good to go
s
But IDEA doesn't mark it as a test source set
e
if it's about whether a source set is marked as a test source set within the IDE, that's a different issue, but can be changed with the
idea
plugin. Gradle itself doesn't care
s
Oh is that an idea concept?
t
src/main src/test src/integration
But IDEA doesn't mark it as a test source set
I don't know what that means.
s
It's blue not green
t
same, but it doesn't matter
s
So that's just an IDEA concept and has no effect on gradle?
t
none whatsoever
I've been running those tests on CI for nearly 3 years
s
Okay, I assumed if IDEA read it was a normal source set, then it was misconfigured
t
IDEA probably has special handling for
test
. I don't know how to tell it something is a test in that view, but I can confirm it still lets you run tests from within the IDE
that's in my
functionalTest
source set
s
Can I make the new source set just use the
testImplementation
deps?
t
Copy code
val functionalTestImplementation = configurations
  .getByName("functionalTestImplementation")
  .extendsFrom(configurations.getByName("testImplementation"))
s
That gives
Copy code
Configuration with name 'functionalTestImplementation' not found.
t
your name would be different 🙂
e
you named yours "integration"
t
integrationImplementation
, I think
s
So it compiles now, but I get "No Tasks Available" when trying to run tests using the IDEA gutter
e
try resync, or invalidate, or remove .idea, or all the usual tricks
j
if you are on junit5 platform, you can use, what i think is better than the separate source set way of doing integration tests, test tags https://www.codingeek.com/tutorials/junit/junit-tag-annotation-filter-example/
s
Would be nice if I can keep my deps separate, but I'll try that if this fails.
g
if you want idea to recognize the source set as tests you'll have to add something like this:
Copy code
pluginManager.withPlugin("idea") {
  the<IdeaModel>().module {
    // using legacy setters since IDEA ignores new ones
    testSourceDirs = testSourceDirs + sourceSet.allSource.sourceDirectories
    testResourceDirs = testResourceDirs + sourceSet.resources.sourceDirectories
  }
}
or use new test suites, they seem to be detected as test sources (at least in 2022.2 beta
j
the official gradle docs also have a section on the sourceset method you can reference: https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests
t
don't forget
Copy code
tasks.withType<Test>().configureEach {
  useJUnitPlatform()
}
or use the test suites thing. YMMV
s
Still didn't work, do I need to add a separate task to run the integration tests somehow?
t
try running from CLI to verify the wiring is correct. If so, then it's an IDE issue and not a Gradle issue
./gradlew <my-module>:integrationTest
e
each test suite is a separate task, you can add them as dependencies to the standard
check
task as the documentation indicates
s
Copy code
Task 'integrationTest' not found in root project 'backend'.
Do I need this part?
t
oh, maybe. I wrote that so long ago 🤔
e
which approach did you take? with tony's you need to manually register the tasks, and choose their name. with the test suite plugin, it's automatic
t
I guess I mis-remembered about tasks being auto-registered. Sorry about that! 😅
other people have already given you examples, but here's another using the test suites plugin if you want something more auto-magic https://github.com/dropbox/dependency-guard/blob/main/dependency-guard/build.gradle.kts#L72-L112
s
The plugin didn't work either
It creates the source set, but I all of my imports break
e
I think it's likely that's an IDE issue - does the test run from Gradle?
s
Doesn't work with gradle either
Same unresolved reference errors
I'm assuming its related to
Copy code
dependencies {
				implementation(project)
			}
Uggh I've wasted 5 hours trying to sort this out now
Just realised
I don't get much time outside of work lol
That plugin just doesn't work
I believe this is adding the project as a dependency, but I want to add the project and all of its depdencies too
Copy code
dependencies {
   implementation(project)
}
j
oh, i dont think you can just depend on an application project
you need a separate configuration
like
Copy code
configurations {
    testApp {
        extendsFrom(runtime)
    }
e
if you want the main configuration, you don't need anything special - it is already included
j
then something like
Copy code
task testJar (type: Jar) {
    from sourceSets.main.runtimeClasspath
}
artifacts {
    testApp testJar
}
s
My dependencies aren't being added to the new test source set@ephemient
Does the plugin handle that or should I use Johns code
j
then depend on it like
Copy code
testImplementation(project(path: ":backend", configuration: "testApp"))
my examples are groovy dsl, you can translate to kotlin if need be
e
there's too many conflicting things going on here.
none of that should be necessary with the jvm-test-suites plugin
s
I'm hoping so, but I don't know what configuration I need to change, because by default, I don't have access to any dependencies from my main project
I got the tests to run by copy pasting all my dependencies
Not ideal, if there's a better way pls let me know
Thanks for your help everyone, I appreciate your time.
e
I wired up a local demo and 1. I was wrong,
implementation(project)
is only implicit for the main test, you should add it explicitly for the additional suites as needed, and 2. with that it seems to work fine for me, so if you have further issues, see if you can share a reproducible example.
s
It does work withoout that, but I cannot access the transitive depdencies of the main project
e
are they
implementation
or
api
in the main configuration? if they're
implementation
, then it doesn't show up in downstream compile classpath by default
if they're used in your exported interfaces then it should be
api
and that makes them in both the compile and runtime classpaths
s
Would be nice if I could just make the
testImplementation
and
implementation
apply to both source sets
e
if you adapt tony's snippet and
Copy code
configurations.getByName("integrationImplementation") {
    extendsFrom(configurations.getByName("implementation"))
    extendsFrom(configurations.getByName("testImplementation"))
}
then that'll happen but that seems kinda questionable. I think it would be better to create a new shared configuration that gets included into everything else, if you want some shared set of internal-only dependencies.
s
Yea sounds sensible
j
For some of the setup discussed here you can also use the new JVM Test Suites to ease the setup: https://docs.gradle.org/current/userguide/jvm_test_suite_plugin.html Although, this might add even more confusion. I give an overview here:

https://youtu.be/7f_gBvGQN_0â–¾