Streets Of Boston
Streets Of Boston

Reputation: 12596

Questions about calabash-android support in Android Studio: Ruby, Editing features and steps, Launching tests

I'm working with Android Studio on Windows 7, 64 bit. I'm a noobie on Android Studio (or any Intelij IDE).

I downloaded and installed Ruby 1.9.3, The Ruby DevKit and calabash-android and I can successfully run Cucumber tests on my Android app using the command line (calabash-android run )

I also managed to install the Cucumber plugin for Android Studio, so that my feature files can benefit from autocomplete and such.

I have the following questions:

Thank you!

Update:

I attached a custom gradle Plugin<Project> (see groove code below that I wrote to have a basic support for running calabash-android tests.

These manual steps are still necessary:
- Install Ruby 1.9.x and its Devkit, install the calabash-android gem, etc.
- Build the appropriate (flavor of an) APK using android gradle plugin (manual or automated)

In the app's build.gradle, adding apply plugin: 'calabash' now works and it allows the build to run a feature file as a calabash test.
It examines the available product-flavors (build-flavors) and adds the appropriate calabash related tasks (e.g. calabashDebug or calabashFlavor1Release, etc).

Below is the groovy file that implements my 'calabash' plugin (Windows only for now):

    package com.mediaarc.gradle.plugins

    import org.gradle.api.*
    import org.gradle.api.plugins.*
    import org.gradle.api.tasks.*

    class CalabashPlugin implements Plugin<Project> {
        void apply(Project project) {
            project.extensions.create("calabash", CalabashPluginExtension)

            if (!project.android) {
                throw new IllegalStateException("Android plugin is not configured.")
            }

            project.android.applicationVariants.each { variant ->
                final def buildName  = variant.name
                final def buildVar   = variant.baseName
                final def packageApp = variant.packageApplication;

                project.task("doPrepare${buildName}") << {
                    project.calabash.init(project, buildVar)
                    def apkFile = packageApp.outputFile
                    project.calabash.writeCommandFile(apkFile)
                }

                project.task("doClean${buildName}") << {
                    project.calabash.init(project, buildVar)

                    project.calabash.clean()
                }

                project.task("calabash${buildName}", type: Exec, dependsOn: [ project["assemble${buildName}"], project["doPrepare${buildName}"] ]) {
                    println project["assemble${buildName}"]
                    project.calabash.init(project, buildVar)
                    configureTask(project[name], buildName)

                    project.calabash.execute(project[name])
                }

                project.task("cleanCalabash${buildName}", dependsOn: project["doClean${buildName}"]) {
                    project.calabash.init(project, buildVar)
                    configureClean(project[name], buildName)
                }
            }
        }

        private def configureTask(def task, def buildVariant) {
            task.group = JavaBasePlugin.VERIFICATION_GROUP
            task.description = "Runs calabash tests for Build '${buildVariant}'"
        }

        private def configureClean(def task, def buildVariant) {
            task.group = BasePlugin.BUILD_GROUP
            task.description = "Deletes the calabash tests results for Build '${buildVariant}'"
        }
    }

    class CalabashPluginExtension {
        def root = 'src/calabash'
        def resultFile = "calabash-results.html"

        //protected def hash = new Object()
        protected File outputFile
        protected File workingDir
        protected File tmpFile

        protected init(Project project, def buildVariant) {
            if (!buildVariant) {
                buildVariant = "debug"
            }

            File rootFile = project.file(root)
            outputFile   = new File(project.file("build/reports/calabash/${buildVariant}"), resultFile)
            workingDir   = rootFile
        }

        protected writeCommandFile(def apkFile) {
            if (!workingDir.exists()) {
                throw new IllegalStateException("The root directory for the calabash-tests could not be found: '${workingDir}'")
            }

            if (!(new File(workingDir, "features").exists())) {
                throw new IllegalStateException("The required 'features' directory could not be found in '${workingDir}'")
            }

            outputFile.parentFile.mkdirs()

            def calabashCmd = "cd ${workingDir.canonicalPath}\r\necho calabash-android run \"${apkFile.canonicalPath}\" --format html --out \"${outputFile.canonicalPath}\"\r\n"
            getCommandFile().write calabashCmd
        }

        protected execute(Exec exec) {
            exec.commandLine 'cmd', '/c', getCommandFile().canonicalPath
        }

        protected clean() {
            outputFile.delete()
        }

        private File getCommandFile() {
            if (!tmpFile) {
                tmpFile = File.createTempFile("run-calabash", ".bat")
                tmpFile.deleteOnExit()
            }
            return tmpFile
        }
    }

Upvotes: 13

Views: 3429

Answers (1)

Jannie Theunissen
Jannie Theunissen

Reputation: 30154

Very good question. Xamarin had a webinar on using Calabash tests in their Test Cloud product. Towards the end of the talk there is quite a bit of hands-on with setting up the testing ecosystem and running Calabash tests for Android. There's lots in there that don't apply to your environment, but some very good tips and insights from Karl Krukow - one of the main contributors to calabash-android.

Upvotes: 3

Related Questions