Skip to content

Join us in simplifying the process of crafting automated acceptance tests for your native Android mobile apps!πŸ“±πŸ€–πŸš€ Let's make it easier together – take action now!" πŸ’ͺπŸ‘‰πŸŒŸ

License

Notifications You must be signed in to change notification settings

kranberry-io/kranberry

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


CI CONTRIBUTORS Stargazers Issues License Forks Last Commit Release Date Visitors

  1. About Kranberry
  2. Getting Started
  3. Kranberry Properties File
  4. Roadmap
  5. Contributing
  6. Templates
  7. License

About Kranberry

Maintaining Android Mobile UI test codes, which are already structured, is relatively easier than starting them from scratch.

Building/adapting an architecture, defining libraries and their compatibilities ends up consuming precious time when we need to build end-to-end functional tests (E2E).

To get around this issue, we developed an Open-source library in order to facilitate the integration of native UI tests for Android in Kotlin, which aims to reduce the time and complexity of initial configuration of these test modules.

Our goal is to provide resources so you can start a test package quickly, while we provide you with settings and features you won't waste time worrying about!


Getting Started

Note that the library is experimental, and the API is subject to change.

The library is published to Maven Central.

To use the Kranberry library, follow the steps:

Setup Kranberry Dependency

Add the Maven Central repository in the root/build.gradle file if it is not already there:

        maven {
            url "https://plugins.gradle.org/m2/"
        }
  1. Add the Kranberry dependency to your module/build.gradle file inside the package that will be tested (not the build.gradle file in the project root):
// Kranberry
androidTestImplementation 'io.github.kranberry-io:kranberry:1.0.1-beta'
  1. Add a kranberry.properties.json file in the path module/src/androidTest/assets. If the folder does not exist, you must create it. πŸ’‘ See the template

  2. Add an AndroidManifest.xml file in the path module/src/androidTest. If the folder does not exist, you must create it. πŸ’‘ See the template

  3. Add an App.kt class in the path module/src/androidTest/java/feature. If the folder does not exist, you must create it. This step will serve to implement the method that will open your app. πŸ’‘ See the template

  4. Add a Home.kt class in the path module/src/androidTest/java/feature. If the folder does not exist, you must create it. This step will serve to implement navigation steps and assertions. πŸ’‘ See the template

  5. Add a test using the pre-implemented App and Home features. If the folder does not exist, you must create it. This step will serve to implement navigation steps and assertions. πŸ’‘ See the template

  6. Add the /kranberry-outputs/ information to your root/gitignore file. This will prevent you from publishing test outputs in your repository.

# Output Files Kranberry Library
/kranberry-outputs/
/app/kranberry-outputs/

Run Tests Using Makefile

  1. If you want to run your tests in a customized way, you can include a Makefile , modifying the execution tasks with desired parameters. πŸ’‘ See the template

πŸ₯³ πŸŽ‰ VoilΓ ! Now you can run your first test from the terminal command line by using make run-kranberry:

Run-Tests-Gif

Note that there is a previously opened emulator to run the tests.

Run Tests Using Kranberry Gradle Plugin

πŸ›  This feature is under construction! But you can use the current version which doesn't have the output printing in the terminal console yet..

  1. Now you can also use the gradle plugin to run the tests from the ./gradlew runKranberryTests command. To do this include the settings in the build.gradle and module:build.gradle files :

root/build.gradle

  • buildscript
    ext.kranberry_version = '1.0.1-beta'
  • dependencies
        classpath "io.github.kranberry-io:runtests:$kranberry_version"

module/build.gradle

apply plugin: "io.github.kranberry-io.runtests"
  • kranberryTests
kranberryTests {
    packageName = "your.app.package"
    packageTests = "your.app.package.test"
    applicationId = "your.app.package"
    apkOutputPath = "build/outputs/apk/debug/app-debug.apk"
    androidTestApkOutputPath = "build/outputs/apk/androidTest/debug/app-debug-androidTest.apk"
    testsRunner = "androidx.test.runner.AndroidJUnitRunner"
}

πŸ₯³ πŸŽ‰ VoilΓ ! Now you can run your first test from the terminal command line by using ./gradlew runKranberryTests


Kranberry Properties File

This is the configuration file used by the library to configure the values that will be used to set the test environment. The file must be located in the src/androidTest/assets directory with name kranberry.properties.json. Below you will find more details about the parameters that can be used:

Properties table

Parameter Description Type Obligatory Default Value
app_packages Packages of the applications that will be tested. The first package in the list will be referenced by the Kranberry constant APP_PACKAGE. The others will be used for permission management. List Yes io.kranberry.sample
clear_application _data_before_testing Defines whether the application data defined in the app_packages parameter list will be cleared before running the tests. Boolean No FALSE
default_timeout Default implicit timeout for interaction with UI elements in milliseconds. Long No 60000
disable_animations Defines whether animations will be disabled during instrumentation tests. The goal is to increase test performance. Boolean No TRUE
max_search_swipes Sets the maximum scroll down/up will be performed when fetching an element using the methods of the io.kranberry.ui.Swipe class. Int No
page_load_timeout Defines the maximum implicit wait time for the element set in the progressbar_class property. This is used in Kranberry's waitForPageLoad() method. Long No 30000
permissions_granted _to_device Defines the list of permissions that will be granted to app packages set in the app_packages property. List No ACCESS_FINE_LOCATION
print_colored_logs Defines if the terminal logs will be printed colored. Boolean No TRUE
progressbar_class Defines the progress bar class that will be implicitly expected. This is used in Kranberry's waitForPageLoad() method. List No android.widget .ProgressBar
skip_chrome_welcome _screen Defines whether the application data defined in the app_packages parameter list will be cleared before running the tests. Boolean No TRUE
swipe_down_params Defines the list of parameters that will be used in method swipeDown(). These being in order: SWIPE_DOWN_START_X, SWIPE_DOWN_START_Y, SWIPE_DOWN_END_X, SWIPE_DOWN_END_Y, SWIPE_DOWN_STEPS List No
swipe_up_params Defines the list of parameters that will be used in method swipeUp(). These being in order: SWIPE_UP_START_X, SWIPE_UP_START_Y, SWIPE_UP_END_X, SWIPE_UP_END_Y, SWIPE_UP_STEPS List No

Example of properties file

{
  "default_timeout": 60000,
  "clear_application_data_before_testing": true,
  "skip_chrome_welcome_screen": true,
  "page_load_timeout": 30000,
  "disable_animations": true,
  "app_packages": [
    "com.android.chrome"
  ],
  "permissions_granted_to_device": [
    "ACCESS_FINE_LOCATION",
    "WRITE_EXTERNAL_STORAGE",
    "READ_EXTERNAL_STORAGE",
    "READ_CONTACTS",
    "CAMERA"
  ],
  "progressbar_class": [
    "android.widget.ProgressBar"
  ]
}

Roadmap

ISSUES-OPEN CLOSED

See the open issues for a list of proposed features (and known issues).


Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Templates

Kranberry Properties

module/src/androidTest/assets/kranberry.properties.json

{
  "default_timeout": 60000,
  "clear_application_data_before_testing": false,
  "skip_chrome_welcome_screen": true,
  "page_load_timeout": 30000,
  "disable_animations": true,
  "app_packages": [
    "your.app.package"
  ],
  "permissions_granted_to_device": [
    "ACCESS_FINE_LOCATION",
    "WRITE_EXTERNAL_STORAGE",
    "READ_EXTERNAL_STORAGE",
    "READ_CONTACTS",
    "CAMERA"
  ],
  "progressbar_class": [
    "android.widget.ProgressBar"
  ],
  "print_colored_logs": true,
  "test-class_prefix": "your.app.package.test"
}

⬅️ ➑️ ⬆️

Android Test Manifest

module/src/androidTest/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.app.package.test">

    <uses-sdk
        android:minSdkVersion="24"
        android:targetSdkVersion="30" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

</manifest>

⬅️ ➑️ ⬆️

App class

module/src/androidTest/java/feature/App.kt

package feature

import androidx.test.uiautomator.UiDevice
import io.kranberry.environment.DeviceHandler.APP_PACKAGE
import io.kranberry.environment.DeviceHandler.start
import io.kranberry.outputs.ScreenshotHandler.takeScreenshot
import io.kranberry.ui.BaseUi

class App(device: UiDevice) : BaseUi(device) {

    fun open(): Home {
        start(APP_PACKAGE)
        takeScreenshot()
        return Home(device)
    }
}

⬅️ ➑️ ⬆️

Home class

module/src/androidTest/java/feature/Home.kt

package feature

import androidx.test.uiautomator.UiDevice
import io.kranberry.outputs.ScreenshotHandler.takeScreenshot
import io.kranberry.ui.BaseUi
import io.kranberry.ui.elementIsPresentByTextContains

class Home(device: UiDevice) : BaseUi(device) {

    fun shouldSeeFlowerList(): Home {
        assert(elementIsPresentByTextContains("Flowers"))
        takeScreenshot()
        return this
    }
}

⬅️ ➑️ ⬆️

Test class

module/src/androidTest/java/your/app/package/YourTestJourney.kt

package your.app.package
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import feature.App
import io.kranberry.KranberryRules
import io.kranberry.environment.TestHandler.device
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = 24)
class YourTestJourney {

    @Rule
    @JvmField
    val testRule = KranberryRules()

    @Test
    fun openApp(){
        App(device)
            .open()
            .shouldSeeFlowerList()
    }
}
}

⬅️ ➑️ ⬆️

Makefile

root/Makefile

### BUILD ####
buildDebug:
	./gradlew assembleDebug

buildAndroidTestDebug:
	./gradlew assembleDebugAndroidTest

### INSTALL ###
installDebug:
	adb install app/build/outputs/apk/debug/app-debug.apk

installAndroidTestDebug:
	adb install app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk

buildInstallDebug: buildDebug installDebug

### TEST ###
testDebug:
	./gradlew testDebug

testFileDebug:
	./gradlew testDebug --tests $(file)

androidTestDebug:
	./gradlew connectedDebugAndroidTest

androidTestDebugModule:
	./gradlew :$(module):connectedDebugAndroidTest

androidTestFileDebugModule:
	./gradlew :$(module):connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=$(file)

clear-logcat-logs:
	@adb shell logcat -b all -c

copy-tests-outputs:
	@rm -rf kranberry-outputs; \
	mkdir kranberry-outputs; \
	adb pull /storage/emulated/0/Android/media/your.app.package kranberry-outputs; \

### RUN UI TESTS ###
# before run tests make sure to call: buildDebug buildAndroidTestDebug installDebug installAndroidTestDebug
test: buildDebug buildAndroidTestDebug installDebug installAndroidTestDebug clear-logcat-logs
	@adb logcat *:S KRANBERRY_LOG:V & LOGCAT_PID=$$!; \
	TERM=dumb adb shell am instrument -w your.app.package.test/androidx.test.runner.AndroidJUnitRunner ; \
	RESULT=$$?; \
	if [ -n "$$LOGCAT_PID" ]; then kill $$LOGCAT_PID; fi; \
	exit $$RESULT

run-kranberry:
	@make test && make copy-tests-outputs

⬅️ ➑️ ⬆️


License

Distributed under the Apache Version 2.0 License. See LICENSE for more information.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

About

Join us in simplifying the process of crafting automated acceptance tests for your native Android mobile apps!πŸ“±πŸ€–πŸš€ Let's make it easier together – take action now!" πŸ’ͺπŸ‘‰πŸŒŸ

Resources

License

Stars

Watchers

Forks

Packages

No packages published