Hi, im trying to run tests before `assembleRelease...
# gradle
u
Hi, im trying to run tests before
assembleRelease
Usually I do it in app build.gradle via
Copy code
afterEvaluate {
    assembleRelease.dependsOn test
}
However this doesnt work for my multimodule app, It seems that code only runs tests in :app I could add that block to every module's build file but that is error prone I tried
Copy code
allprojects {
   afterEvaluate {
       assembleRelease.dependsOn test
   }
}
Copy code
* What went wrong:
A problem occurred configuring root project 'icewarp-teamchat-android'.
> Could not get unknown property 'assembleRelease' for root project 'abc' of type org.gradle.api.Project.
d
Try
subprojects
instead of
allprojects
.
u
Copy code
subprojects {
    afterEvaluate {
        println tasks
    }
}
same as allprojects, I dont see neiter
assembleRelease
not `test`˛in the list
@Dominaezzz
d
Then where are they?
Copy code
afterEvaluate {
    assembleRelease.dependsOn(':app:test')
}
u
I dont know, but they exist I can run them manually, I think some evaluation timing is the issue
@Dominaezzz that wont work, I cannot see assembleRelease, and even if I could, youd depend on the app:test only
d
Hmm, not sure why this is happening.
u
I feel this is stupid anyways, there must be a hook into global assembleRelease to run global test task, not per module
Copy code
allprojects {

    afterEvaluate {
        // Run each module's test task after each module's assembleRelease
        tasks.whenTaskAdded { task ->
            if (task.name == "assembleRelease") {
                task.dependsOn "test"
            }
        }
this works
d
Wow, that's some seriously lazy task config.
Glad there's a solution still.
u
I was surprised this not being easily googlable, but it seems that CIs run simply a command gradlew test, they dont care about internal gradle tasks etc
g
It also quite error-prone, because if you have different flavors it will not run test One problem is that module just don’t have assembleRelease, it has just assemble, for example pure JVM module, it will do nothing and test will not be run
u
you can bake that flavor support in the task name string, but yea .. is there a better way? this feels needlessly brittle
g
I would use proper task for this
that does exactly what you want
instead adding it to assembleRelease
u
what do you mean proper task? @gildor how else do you build your releases other than assembleRelease?
g
I release using own publishing task, and this task depends on
check
task
Gradle provides a few “lifecycle” tasks, that do nothing but just hooks for other tasks: build, assemble, check
and check is a hook that should be used for all test tasks (it’s already true for test tasks)
I don’t want to say that there is easy way, unfortunately, because of more complicated project structure for Android, check and test do not exactly what you usually want, but I think it’s still good rule: configure each module in a way that attach different behaviors to lifecycle, so before publish you just run check that runs all tasks with tests
again, it’s not something ready to use, but I think it’s better to be explicit instead implicit convention with assembleRelease task
u
I might be missing something, how do you actually build release if not with assemble<X>Release? regardless if this is triggered by your custom task or not, something still needs to call that
g
build it with a task that runs your tests and runs assembleRelease
u
well thats my point, that you need to hardcode or somehow parametrize the assembleXRelease in it, therefore you have the same brittleness I think, as that x.dependsOn test
from what I understand you just created customTask.dependsOn assembleRelease.dependsOn test
g
no
you implicitly add those dependencies
my point that every module or every type of module knows what should be checked
and you explitly run this check/test task
u
so root should whitelist all modules tests tasks?
g
no, every module should run own test tasks
u
well, who tells them to run them?
root test task?
g
no
u
then I dont understand
g
when you run
check
it will execute task with this name in all modules
not root, but every module has own
u
yes, prefixless check/test
g
this is how Gradle task work
yes
u
thats why I meant by root
g
it’s bad name for it
it’s not root, root module also may have
test
task
u
okay top level test
g
but when you run task without full path, Gradle just tries to run this task in all modules
no
you probbably don’t understand how gradle task execution works
./gradlew test - means please, run task with name “test” in all modules, where this task exist. UPD: And do nothing for modules where this task doesn’t exist
./gradflew moduletest - run task with name “test” in module with name “module”
u
well, gradle is a mistery most of the time but that I know 😀
g
./gradlew :test - means please, run task with name “test” in root module
u
okay but, how can I have test task fail the release task?
I thought thats accomplished by assembleRelease.dependsOn test
g
yes, it will
every task in graph in case of fail will fail the build
u
okay but in terms of how woukd the task look
isnt it chain of x.dependsOn y?
g
does it make sense which task is fail and order of them?
u
not sure what you mean, Id fail the task on first error
g
yes, this what will happen
again, I think, that assembleRelease.dependsOn test is not right approach
assemble is just assemble, it shouldn’t test anything, this is the point of this task
u
right but what is the gradle syntax? I thought it was assembleRelease dependsOn test
g
assemble on Jvm module doesn’t run tests
u
Im not arguing, with gradle im mostly bashing it until it works
g
it just assemble project, there is
build
lifecycle task which assemble and check the project
Yes, syntax is correct
but Android modules don’t have
test
task by default, at least as I remember, thehy have only testDebugUnit
u
Im confused, if you say its correct then whats wrong
you say assembleReleade.dependsOn test breaks the lifecycle separation thing
g
I;’m saying that it’s wrong approach to add test to dependencies of assemble
not a problem of syntax
u
then how should I have test be prerequisite of assembleRelease?
g
for example ruse
build
lifecycle task that builds only assembleRelease and run tests
This is was my original argument
That no need to add dependencies to assembleRelease, this task does exactly what it should do
at least this is how I see it
u
build
already does that?
doesnt build build every type and flavor etc?
g
nope, but you can implement it
doesnt build build every type and flavor etc?
yes, most probably this is default behavior
you always can have buildRelease
u
Okay, but via what syntax if not the dependsOn?
g
or something like this
I said nothing about syntax
I’m telling about semantics
I also think that it’s inccorrect how Android plugin configures graph and add lint as dependency to release task
u
well
Copy code
task buildRelease {
   assembleRelease.dependsOn test
}
g
nope
u
is where we started with
g
Copy code
task buildRelease {
   dependsOn assembleRelease test
}
u
yea didnt know you could do that, thanks
g
just a task that depends on 2 other tasks
u
btw will that work the way you wrote it? Since assembleRelease becomes available later in time etc.
g
what do you mean? are you applying it in allprojects?
assembleRelease make sense only for application module, so it should be configured there
you can use afterEvaluate of course
I use custom plugins, but also it’s possible to do using plugin application hooks. plugin.withType(LibraryPlugin) etc
u
Well I thought that buildDelease task should be in project level build.gradle, since its top level or whatever the naming
g
It’s possible to do of course
we use custom gradle plugins to share any config, so it’s always explicit
u
Hi @gildor, so I tried it
Copy code
task buildRelease() {
    dependsOn "assembleRelease", "test"
    group "build"
    description "Build release apk for deployment and runs tests"
}
If I put that in app/build.gradle then, it builds release however only runs apptest, not library modules So, I tried putting it in project build.gradle and I get
Copy code
* What went wrong:
Could not determine the dependencies of task ':buildRelease'.
> Task with path 'test' not found in root project 'icewarp-teamchat-android'.
which I dont understand, I see it there
g
Do you really have test task on your root project? Does it Android or Java module itself?
u
Not sure what you mean; its an android project; its generated by someone automatically, all project seem to have it for me
g
but do you apply android plugin to this module? looks that it’s your root project
u
no its the root, has no plugins
g
so, if so you don’t have test there
u
yes I do, i posted the screenshot
g
This is just idea representation
run
:test
u
Copy code
* What went wrong:
Task 'test' not found in root project 'icewarp-teamchat-android'.
so where should I put the buildRelease so it works with prefixless
test
? I would not expect the task physical location to matter if it references :module or prefixless explicitly