szpak / gradle-pitest-plugin

Gradle plugin for PIT Mutation Testing
http://gradle-pitest-plugin.solidsoft.info/
221 stars 58 forks source link

Support Kotlin Multiplatform Mobile plugin #234

Open dalewking opened 4 years ago

dalewking commented 4 years ago

As requested here would like to have support for kotlin multiplatform mobile plugin. I have it working with a manually created gradle task and the command line version of pitest.

If you need a KMM Appication to test with you can follow these instructions.

The goal is to run pitest on the commonMain classes using the tests in commonTest using the setup for the testDebugUnitTest task.

If it would be of help here is the things I did in our project to create a pitest task in the shared project. First creating a pitest configuration (Note we use the io.spring.dependency-management plugin which is why there are no version numbers):

configurations {
    pitest
}

dependencies {
    pitest 'org.pitest:pitest-command-line'
    pitest 'com.github.pitest:pitest-kotlin'
}

And the actual task:

task pitest(type: JavaExec, group: "verification") {
    outputs.dir("$buildDir/pitest")
    description = "Run PIT mutation testing."
    main = "org.pitest.mutationtest.commandline.MutationCoverageReport"

    doFirst {
        // PITest outputs a spinner to show activity unless you turn on verbose mode
        // which garbles the output of gradle. This filters out the spinner characters
        // until it gets real output which does not happen until it is done.
        standardOutput = new FilterOutputStream(System.out) {
            boolean filtering = true

            @Override
            void write(int b) throws IOException {
                if (filtering)
                    switch (b) {
                        case 92: // \
                        case 124: // |
                        case 47: // /
                        case 45: // -
                        case 8: // Backspace
                            return
                        default:
                            filtering = false
                            break
                    }

                super.write(b)
            }
        }

        tasks.named("testDebugUnitTest", Test) {
            classpath(
                configurations.pitest,
                it.classpath
                    // Don't do logging of tests during pitest
                    .filter { !it.toString().contains("slf4j-simple") }
            )
        }
    }

    args "--reportDir=$buildDir/pitest",
         "--sourceDirs=$projectDir/build/srclink,$rootDir/pureCloudApi/src/commonMain/kotlin",
         "--targetClasses=$pitest_target_classes",
         "--targetTests=com.genesys.purecloud.wfmshared.*",
         "--mutableCodePaths=$rootDir/pureCloudApi/build/libs/pureCloudApi-jvm-1.0.0.jar," +
                 "$projectDir/build/intermediates/javac/debug/classes," +
                 "$projectDir/build/tmp/kotlin-classes/debug",
         "--timestampedReports=false.",
         "--threads=6"

    if(pitest_verbose == "true") args += "--verbose"

    dependsOn makeSourceLink
    dependsOn "compileDebugUnitTestSources"
}

The pureCloudApi stuff is another module in the project that is generated using openApiGenerator.

It is using 2 gradle properties with the default set in gradle.properties for controlling verbose mode and the target classes (so that you can focus on a file or package)

I have another task that inlines the css style into the report because our Jenkins requires authentication and loading the CSS file does not work, but this is probably outside the scope:

// Because access to jenkins is authenticated and css is loaded without any cookies
// it cannot load the css file. This task copies the report and inlines the CSS
task inlinePitestReportCss(type: Copy) {
    into("$buildDir/pitest-inlined")
    from(pitest.outputs) {
        include "**/*.html"
        filter {
            if(it.contains("<link rel=\"stylesheet\" type=\"text/css\"")) {
                "<style type='text/css'>\n" +
                file("$buildDir/pitest/style.css").text +
                "\n</style>"
            }
            else
                it
        }
    }

    dependsOn pitest
}
JavierSegoviaCordoba commented 1 year ago

This year KMP becomes stable. Is this on the roadmap?

szpak commented 1 year ago

Looking at KMP, it seems to be for the Android projects. @koral-- Maybe it would better fit your Android fork of GPP?

JavierSegoviaCordoba commented 1 year ago

What do you mean with Android projects? Android is one of the multiple targets KMP has

szpak commented 1 year ago

What do you mean with Android projects? Android is one of the multiple targets KMP has

I mean, this project (szpak/gradle-pitest-plugin) is for regular Java projects (no mobile). The Android projects (and things related to the Android Gradle plugin) are covered by the fork (koral--/gradle-pitest-plugin). As Android is one of the target, it (most likely - I don't know the project internals) will not work with this project and I proposed the fork. I have no idea about the support for iOS part.

CLOVIS-AI commented 8 months ago

Kotlin Multiplatform is a technology to compile Kotlin code to multiple targets. JVM is one of them, Android is another. JS and WASM are others as well.

I personally use Kotlin/JVM for my backends and Kotlin/JS for my frontends. The Kotlin Multiplatform Gradle plugin creates different source sets for different platforms; the JVM platform is identical to any other JVM platform. Currently, I cannot use this project for my JVM code because the Kotlin Multiplatform plugin is not supported. As I am not doing mobile development, I do not believe this issue is in scope for the Android fork.