Search code examples
javagradlegradlewmulti-project

Gradle can't find package in dependent test project


I'm trying to run ./gradlew build for a nested multi project structure and I'm running into issues that only seem to appear for projects with test source roots. Being new to both java and gradle I'm sure I'm breaking more than one convention, but I still think this should be working.

Essentially, all the dependencies seem to be added fine, but when I have one project that only has a Test srcDir that depends on another project that has a Test srcDir, it doesn't recognize packages/symbols in that root project. However, projects with regular srcDirs (not test) don't seem to have a problem.

My project has more going on than this, but here is the simplest setup I've tried that illustrates the problem.

My project structure:

qatests
    /Applications
        /AppGroupName
            /AppBasePageObjects
                /src
            /AppBaseTests
                /src
    /BasePageObjects
        /src
    /BaseTests
        /src

My settings.gradle in qatests:

rootProject.name = 'QaTests'
include 'BasePageObjects'
include 'BaseTests'
include 'Applications:AppGroupName'
include 'Applications:AppGroupName:AppBasePageObjects'
include 'Applications:AppGroupName:AppBaseTests'

My build.gradle in qatests:

version '1.0-SNAPSHOT'

allprojects {
    repositories {
        mavenCentral()
    }
}

subprojects{

    if(project.name.contains("Tests")){
        apply plugin: 'java'
        sourceCompatibility = 1.8
        dependencies {
            testCompile group: 'junit', name: 'junit', version: '4.11'
            compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+'
        }

        if(project.name != "BaseTests")
        {
            println "$project.name depends on BaseTests"
            dependencies {
                testCompile project(':BaseTests')
            }
        }

        sourceSets {
            test {
                java {

                    srcDir 'src'
                }
            }
        }
    }

    if(project.name.contains("PageObjects")){
        apply plugin: 'java'
        sourceCompatibility = 1.8
        dependencies {
            compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+'
        }

        if(project.name !="BasePageObjects")
        {
            dependencies {
                compile project(':BasePageObjects')
            }
        }

        sourceSets {
            main {
                java {

                    srcDir 'src'
                }
            }
        }
    }
}

I won't include my build.grade for the BaseTest project since that seems to compile fine during the gradlew build, but here is my build.gradle for AppBaseTests:

version '1.0-SNAPSHOT'

dependencies {
    compile 'org.apache.commons:commons-lang3:3.4'
    compile project(':Applications:AppGroupName:AppBasePageObjects')
}

When I run ./gradlew build in the qatests root, the BaseTests, BasePageObjects, and AppBasePageObjects projects seem to compile fine and AppBasePageObjects successfully uses packages and symbols from BasePageObjects. For some reason however, AppBaseTests can't seem to recognize packages and symbols in BaseTests.

If I clone this project from scratch, IntelliJ runs the gradle scripts scripts automatically and everything seems to work out of the box just fine with the dependencies, so this just confuses me even more.

I've tried adding compile and testcompile for all the project dependencies since that's the only real difference between AppBasePageObjects which works and AppBaseTests which doesn't work. I've also tried adding compileJava.dependsOn(':BaseTests:build') to the AppBaseTests build.gradle file. And a few other rabbit holes, but nothing seems to have any effect on this dependency issue.

For what it's worth, here is the first error I see in the actual build:

error: package Tests does not exist import Tests.BaseTest;

Any help or suggestions are greatly appreciated. If you would like to distribute some harsh insults I'll take those as well. Thank you.


Solution

  • I believe I found an answer while reading another solution here: Multi-project test dependencies with gradle

    It seems I needed to use testCompile project(':BaseTests').sourceSets.test.output for command line builds as well as testCompile project(':BaseTests') for IDE functionality in my root build.gradle file. This only seems to be required for the test projects.

    Here are the actual changes in my root build.gradle file:

        if(project.name != "BaseTests")
        {
            println "$project.name depends on BaseTests"
            dependencies {
                testCompile project(':BaseTests')
                testCompile project(':BaseTests').sourceSets.test.output
            }
        }
    

    This seems a bit hacky but works, if somebody has a more thorough and intelligent answer please post!