Giter VIP home page Giter VIP logo

test-butler's Introduction

Test Butler

Build Status Maven Central

Reliable Android testing, at your service.

Motivation

Test Butler was inspired by the Google presentation "Going Green: Cleaning up the Toxic Mobile Environment". For more background, read the Test Butler announcement blog post.

What does it do?

  • Stabilizes the Android emulator, to help prevent test failures caused by emulator issues.
    • Disables animations so Espresso tests can run properly.
    • Disables crash & ANR dialogs so a system app misbehaving won't trigger a popup that causes your UI tests to fail.
    • Locks the keyguard, WiFi radio, and CPU to ensure they don't go to sleep unexpectedly while tests are running.
    • Disables system spell checker to avoid redline highlights and text auto correction.
  • Handles changing global emulator settings and holds relevant permissions so your app doesn't have to.
    • Enable/disable WiFi: Test Butler allows tests to simulate a situation where WiFi is not connected or changes availability at some point.
    • Change device orientation: Tests can manually set the orientation of the device during test execution.
    • Set location services mode: Test Butler lets your code simulate different location services modes, like battery saver or high accuracy.
    • Set application locale: Tests can set a custom Locale object for their application to simulate running the app in another language.
    • Grant runtime permissions: Tests can grant Marshmallow's runtime permissions to their application directly from test code.
    • Use hardware IME: Tests can tell the system to prefer the hardware IME.
    • Control immersive mode confirmation: Tests can enable or disable immersive mode confirmation.

How does it work?

Test Butler is a two-part project. It includes an Android library that your test code can depend on, as well as a companion Android app apk that must be installed on your Android emulator before using Test Butler. You can build the Test Butler APK yourself from source, or download the binary from Maven Central

The Test Butler library is a thin wrapper around an AIDL interface to give your tests a safe way to talk to the Test Butler app's service running in the background on the emulator.

The Test Butler app is signed using the system keystore for the Android emulator, so it is automatically granted signature-level permissions when installed. This means granting permissions via adb is not necessary. It also means that this app can only be installed on emulators that use the stock Android keystore!

Being a system app makes Test Butler much easier to use than existing Android solutions for changing emulator settings. To disable animations, you just need a single line of code in your app; no extra permissions in your debug manifest, no granting permissions via adb, no Gradle plugin to integrate.

Test Butler can even use permissions that can't be granted via adb, like the SET_ACTIVITY_WATCHER permission, which lets Test Butler disable crash & ANR dialogs during tests.

Any "gotchas" to look out for?

Only a few:

Test Butler helper app requires an emulator image with stock Android else it won't install, therefore it will not work with non-stock emulator images such as ones with Google APIs or Google Play!

Test Butler adds a custom IActivityController to the system to be able to suppress crash & ANR dialogs. This technique is also used internally by the Monkey tool. Unfortunately, the implementation of the isUserAMonkey() method takes advantage of the fact that the Monkey class is the only thing inside Android that sets an IActivityController and returns true whenever one is set.

This means that isUserAMonkey() will return true while Test Butler is running! If your app uses this method to invoke different behavior during actual monkey testing, you may encounter issues while running tests with Test Butler. An easy fix is to create a helper method in your app to call instead of isUserAMonkey(), which returns false while instrumentation tests are running and calls through to the real isUserAMonkey() when the app is not being instrumented.

Download

Download the latest .apk and .aar via Maven:

    <dependency>
      <groupId>com.linkedin.testbutler</groupId>
      <artifactId>test-butler-library</artifactId>
      <version>2.2.1</version>
      <type>pom</type>
    </dependency>
    <dependency>
      <groupId>com.linkedin.testbutler</groupId>
      <artifactId>test-butler-app</artifactId>
      <version>2.2.1</version>
      <type>pom</type>
    </dependency>

or Gradle:

    androidTestImplementation 'com.linkedin.testbutler:test-butler-library:2.2.1'
    androidTestUtil 'com.linkedin.testbutler:test-butler-app:2.2.1'

You can also download the apk file manually from Maven Central if you prefer.

Getting Started

Install the Test Butler apk on your emulator prior to running tests, then add the following to your test runner class:

public class ExampleTestRunner extends AndroidJUnitRunner {
  @Override
  public void onStart() {
      TestButler.setup(getTargetContext());
      super.onStart();
  }

  @Override
  public void finish(int resultCode, Bundle results) {
      TestButler.teardown(getTargetContext());
      super.finish(resultCode, results);
  }
}

To change settings on the device from your tests, just use the methods in the TestButler class. For example:

@Before
public void setup() {
  TestButler.setLocationMode(Settings.Secure.LOCATION_MODE_OFF);
}

@Test
public void verifyBehaviorWithNoLocation() {
  // ...
}

@After
public void teardown() {
  TestButler.setLocationMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
}

NB: See gotchyas above to see why @BeforeClass & @AfterClass aren't used here.

Snapshots

You can use snapshot builds to test the latest unreleased changes. A new snapshot is published after every merge to the main branch by the Deploy Snapshot Github Action workflow.

Just add the Sonatype snapshot repository to your Gradle scripts:

repositories {
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots/"
    }
}

You can find the latest snapshot version to use in the gradle.properties file.

test-butler's People

Contributors

alexbeggs avatar andreij7 avatar bootstraponline avatar cckroets avatar chao2zhang avatar cs-victor-nascimento avatar drewhannay avatar ethankhall avatar ewolfe123 avatar handstandsam avatar izzytwosheds avatar jasmsu avatar kisty avatar kkoser avatar li-wjohnson avatar mockitoguy avatar plastiv avatar realdadfish avatar sagar-waghmare-rsl avatar skart1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

test-butler's Issues

Add change font size

Being able to change font size would be super helpful especially for testing large fonts on screens. Would this be possible?

setRotation will only work with a delay

changing the orientation with TestButler.setRotation doesn't

// landscape
TestButler.setRotation(Surface.ROTATION_90);
// Thread.sleep(5000);   <-- this will fix it

isLandscapeLayoutVisible();  <-- this will fail if no Thread.sleep is placed after setRotation

// portrait
TestButler.setRotation(Surface.ROTATION_0);

Switching from offline back to online

Hi there!

I have this two methods in my test-class:

public class ContentLoaderTest {

    @Test
    public void loadContent() throws Exception {

        // just for sure enable both internet connection types
        TestButler.setGsmState(true);
        TestButler.setWifiState(true);

        // place Thread.sleep(5000) here and everything is fine ;)

        // networking here is failing

    }

    @Test
    public void loadContentOffline() throws Exception {

        TestButler.setGsmState(false);
        TestButler.setWifiState(false);

        try {

            // networking here seems to be offline

        } finally {
            // enable it again
            TestButler.setGsmState(true);
            TestButler.setWifiState(true);
        }

    }

}

Method loadContentOffline() is started first and even if internet connectivity is reenabled again the second method is offline. It works with Thread.sleep().

Package has not requested permission

InvocationTargetException while granting permission

Caused by: java.lang.SecurityException: Package com.example.app has not requested permission android.permission.READ_EXTERNAL_STORAGE

Any idea why I'm seeing an invocation target exception? I'm using the same code on a different app and there's no problem.

I'm using an API 25 emulator. Using test butler on a different app with the same test code works.

private boolean permissionGranted(String permission) {
    int checkPermission = ContextCompat.checkSelfPermission(getTargetContext(), permission);
    return checkPermission == PERMISSION_GRANTED;
}

private void grantPermission(String permission) {
    if (permissionGranted(permission)) return;

    TestButler.grantPermission(getTargetContext(), permission);

    if (!permissionGranted(permission)) {
        throw new RuntimeException("Failed to grant " + permission);
    }
}

private void enableScreenshots() {
    grantPermission(READ_EXTERNAL_STORAGE);
    grantPermission(WRITE_EXTERNAL_STORAGE);
}

@Override
public void onStart() {
    TestButler.setup(InstrumentationRegistry.getTargetContext());

    enableScreenshots();
}

TestButler should close system dialogs that are shown at the moment it is starting

We in our team have faced some problem: before our test have started(and testButler was initialised) google play services have have crashed - so System Dialog appeared and test did not pass

Is there any instrument which allows testButler to close already opened dialogs?
Should it be used when testButler is starting?

P.S. We have made a solution based on uiautomator - but I am not sure it is the best one:

 UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        UiObject crashMessageView = uiDevice.findObject(new UiSelector().resourceId(("android:id/message")));
        if (crashMessageView != null) {
            try {
                TestLog.w("Crash alert is found = " + crashMessageView.getText());
                uiDevice.findObject(new UiSelector().resourceId(("android:id/button1"))).click();
            } catch (UiObjectNotFoundException e) {
                TestLog.w("Could not click on crash dialog\n " + e);
            }
        }

Locale changer do not work on Android8

Locale changer do not change Android8-Emulator.
I have tried change locale using setLocale method and this method not able to change locale on Android8 devices.

OS: Android8
device: Emulator

How to use test-butler on api 27?

I see that 1.3.2 has fixed api 27 behaviour, but how is it possible to use it? I thought that all emulators are not using AOSP debug key and I have next exception

adb: failed to install .gradle/caches/modules-2/files-2.1/com.linkedin.testbutler/test-butler-app/1.3.1/534d6fcca0226273c96be9f0fc63c5f4414d34a9/test-butler-app-1.3.1.apk: 
Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Package couldn't be installed in /data/app/com.linkedin.android.testbutler-82hDKADFGk6uWhXHMp5KIQ==: 
Package com.linkedin.android.testbutler has no signatures that match those in shared user android.uid.system; ignoring!]

Any hints how to use test-butler on emulator or device api27+?

Disable spell-checker

Another source for flakyness in tests is the spell-checker as this can pop-up suggestions and then tests fail. So my suggestion for an enhancement would be to disable spell-checking like animations

Indicate in test results if the emulator doesn't have the test-butler app installed

Whenever I run the tests on an emulator without the test-butler app installed, it skips the test butler tests. There's no indication that they have been installed. Is it possible to insert in the exception message that the apk isn't installed.

:app:connectedDevDebugAndroidTest
Tests on Nexus_4_API_23_HARD(AVD) - 6.0 failed: Test run failed to complete. Expected 54 tests, received 49
:app:connectedDevDebugAndroidTest FAILED

Permission denied even after granting WRITE_EXTERNAL_STORAGE successfully

I'm writing to android.os.Environment.getExternalStorageDirectory() after verifying that external storage permission has been granted.

new File(android.os.Environment.getExternalStorageDirectory(), "test.txt").createNewFile()
java.io.IOException: Permission denied

I'm always seeing permission denied errors. I thought test-butler was suppose to fix this. I'm using an API 25 emulator. Permission granted is returning true on both app and test context.

java.io.FileNotFoundException: /storage/emulated/0/com.example.app.FlakyTest_displaysPageObjects_1.png (Permission denied)

Where is the artifact located?

Hi,

added the described androidTestCompile 'com.linkedin.android.testbutler:test-butler-library:1.0.0' but I get > Could not find com.linkedin.android.testbutler:test-butler-library:1.0.0.

Tried search maven.org and bintray.com but nothing is there.

Run demo app tests on travis builds

Now that we've added a sample app (in #7), we can write tests for the project. We should be running those tests on every travis build. This will require a way to install the Test Butler app on the emulator in travis before running tests.

Test butler as standard application

In our company we are building android testing farm which consist not only from virtual devices but also has some real devices. Installing system signed application on a such device is really painfully.
So it will be great to have to assembles of this application:

  1. Full-functionality signed with system key
  2. Reduced functionality - unsigned, but still able to rotate screen, disable wi-fi and etc. As this actions may be done by linear application

java.lang.NoClassDefFoundError: android.provider.Settings$Global

test-butler 1.4.0 crashes on a emulator with SDK level 15 with:

I/ActivityManager( 1259): Start proc com.linkedin.android.testbutler for service com.linkedin.android.testbutler/.ButlerService: pid=1784 uid=1000 gids={1015, 3002, 3001, 3003}
E/AndroidRuntime( 1784): FATAL EXCEPTION: main
E/AndroidRuntime( 1784): java.lang.NoClassDefFoundError: android.provider.Settings$Global
E/AndroidRuntime( 1784):        at com.linkedin.android.testbutler.AlwaysFinishActivitiesChanger.getAlwaysFinishActivitiesState(AlwaysFinishActivitiesChanger.java:62)
E/AndroidRuntime( 1784):        at com.linkedin.android.testbutler.AlwaysFinishActivitiesChanger.saveAlwaysFinishActivitiesState(AlwaysFinishActivitiesChanger.java:39)
E/AndroidRuntime( 1784):        at com.linkedin.android.testbutler.ButlerService.onCreate(ButlerService.java:153)
E/AndroidRuntime( 1784):        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
E/AndroidRuntime( 1784):        at android.app.ActivityThread.access$1600(ActivityThread.java:123)
E/AndroidRuntime( 1784):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
E/AndroidRuntime( 1784):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 1784):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 1784):        at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime( 1784):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1784):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 1784):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime( 1784):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime( 1784):        at dalvik.system.NativeStart.main(Native Method)

Where do I get the TestButler APK from?

Is it not in the repo? Just had a quick look and cannot find anything.

Do we have to build it ourselves? Not sure why we would have to do that. Might be a good addition to the repo if I'm not just being a bit blind.

API to detect if animations are enabled?

AnimationDisabler has disableAnimations and enableAnimations however there's no method to detect the status of animations. This is useful to assert that animations are actually disabled.

What do you think about adding getAnimationScaleFactors?

Clean up activities

One issue I've run into using test-butler with Espresso testing, is that activities don't get cleaned up. I've had to adopt code like this to make sure activity.finish(); gets called after tests run.

  • Is cleaning up activities beyond the scope of test butler?
  • How does linkedin deal with retrying failed tests if there's no way to close the activities from a failed run?

Crash not dismissed

During emulator startup I experience the crash "launcher3 has stopped". When running tests I see that the dialog is not dismissed automatically and my tests are failing with:
java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong.

I've followed the readme: installed the app on emulator, created and enabled custom testrunner, added library to androidTestCompile task.

Thanks for the help,
Marco

Crash from java.lang.AbstractMethodError: abstract method "int android.app.IActivityController.appEarlyNotResponding(java.lang.String, int, java.lang.String)

I've noticed occasional crashes like this in test butler:

04-25 17:19:20.398  2362  2447 D [...]
04-25 17:19:20.823  1235  1256 W BroadcastQueue: Receiver during timeout: BroadcastFilter{7d66486 u0 ReceiverList{1b2a5161 1503 com.android.systemui/10012/u0 remote:9f6ccc8}}
04-25 17:19:21.954  2362  3207 D [...]
04-25 17:19:26.111  2362  3243 D [...]
04-25 17:19:27.156  2421  2435 E JavaBinder: *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
04-25 17:19:27.156  2421  2435 E JavaBinder: java.lang.AbstractMethodError: abstract method "int android.app.IActivityController.appEarlyNotResponding(java.lang.String, int, java.lang.String)"
04-25 17:19:27.156  2421  2435 E JavaBinder:     at android.app.IActivityController$Stub.onTransact(IActivityController.java:106)
04-25 17:19:27.156  2421  2435 E JavaBinder:     at android.os.Binder.execTransact(Binder.java:446)
04-25 17:19:29.056  2362  3207 D [...]
04-25 17:19:29.056  2362  2397 D [...]
--------- beginning of crash
04-25 17:19:29.368  2421  2435 E AndroidRuntime: FATAL EXCEPTION: Binder_2
04-25 17:19:29.368  2421  2435 E AndroidRuntime: Process: com.linkedin.android.testbutler, PID: 2421
04-25 17:19:29.368  2421  2435 E AndroidRuntime: java.lang.AbstractMethodError: abstract method "int android.app.IActivityController.appEarlyNotResponding(java.lang.String, int, java.lang.String)"
04-25 17:19:29.368  2421  2435 E AndroidRuntime:     at android.app.IActivityController$Stub.onTransact(IActivityController.java:106)
04-25 17:19:29.368  2421  2435 E AndroidRuntime:     at android.os.Binder.execTransact(Binder.java:446)
04-25 17:19:32.766  1503  1503 I Choreographer: Skipped 100 frames!  The application may be doing too much work on its main thread.
04-25 17:19:41.948  2362  3245 D [...]
04-25 17:19:44.042  2421  2435 V NoDialogActivityController: appCrashed: com.linkedin.android.testbutler:2421 java.lang.AbstractMethodError java.lang.AbstractMethodError: abstract method "int android.app.IActivityController.appEarlyNotResponding(java.lang.String, int, java.lang.String)" java.lang.AbstractMethodError: abstract method "int android.app.IActivityController.appEarlyNotResponding(java.lang.String, int, java.lang.String)"
04-25 17:19:44.042  2421  2435 V NoDialogActivityController:     at android.app.IActivityController$Stub.onTransact(IActivityController.java:106)
04-25 17:19:44.042  2421  2435 V NoDialogActivityController:     at android.os.Binder.execTransact(Binder.java:446)
04-25 17:19:45.158  2362  2447 D [...]
04-25 17:19:46.429  1235  1256 W ActivityManager: Force-killing crashed app com.linkedin.android.testbutler at watcher's request
04-25 17:19:46.531  1235  1256 I ActivityManager: Killing 2421:com.linkedin.android.testbutler/1000 (adj 1): crash

If I'm reading that right it sounds like some kind of ANR on the system (some other log messages around the time suggest that things are running pretty slowly on the emulator) but then test butler doesn't implement an abstract callback method for IActivityController which causes a crash?

Running on an API 21 x86 emulator, I believe revision 3.

java.lang.NoSuchMethodException: setActivityController

Hi All,
I have issue when run code . My error :
Failed to install custom IActivityController: setActivityController [interface android.app.IActivityController]
java.lang.NoSuchMethodException: setActivityController [interface android.app.IActivityController]
at java.lang.Class.getMethod(Class.java:1981)
at java.lang.Class.getDeclaredMethod(Class.java:1960)

error at method :
private static void setActivityController(@nullable IActivityController activityController) {
try {
Class<?> amClass = Class.forName("android.app.ActivityManagerNative");
Method getDefault = amClass.getMethod("getDefault");
Object am = getDefault.invoke(null);
Log.d(TAG, "setActivityController: " + am.getClass());
Method setMethod = am.getClass().getDeclaredMethod("setActivityController", new Class[]{IActivityController.class});
setMethod.invoke(am, activityController);
} catch (Throwable e) {
Log.e(TAG, "Failed to install custom IActivityController: " + e.getMessage(), e);
}
}

Can you tell me how to fix this error ?

sharedUserId changed on newer Android versions

When I try to install the companion app on Android 8.0 or newer, an error occured:
Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Package couldn't be installed in /data/app/com.linkedin.android.testbutler-nLhD7yL27dgN1HH_nNoQDQ==: Package com.linkedin.android.testbutler has no signatures that match those in shared user android.uid.system; ignoring!]

Looks like, the sharedUserId android.uid.system has changed.

'No tests were found' error

Hi, I'm facing some difficult trying to start using test-butler.
First, I've created another class that extends AndroidJUnitRunner:

public class CustomTestRunner extends AndroidJUnitRunner {
  @Override
  public void onStart() {
    TestButler.setup(InstrumentationRegistry.getTargetContext());
    super.onStart();
  }

  @Override
  public void finish(int resultCode, Bundle results) {
    TestButler.teardown(InstrumentationRegistry.getTargetContext());
    super.finish(resultCode, results);
  }
}

Then I changed this line on my build.gradle app:

defaultConfig{
    testInstrumentationRunner "com.example.heitorcolangelo.espressotests.CustomTestRunner"
}

But when I run my tests, I got 'No tests were found' error.

Second, how can I install the Test Butler apk? Should I clone the project and build it?
Can you help me with theses two points please?
Thanks!

Fix information in the README

Hello,
your README states:

the test suite will not report that the Test Butler app is not installed, instead it will skip the test.

However, I am continually getting this exception:
java.lang.IllegalStateException: ButlerService is not started!

When trying to use TestButler without the companion APK.

TestButler should be able to disable an immersive mode dialog

When activity is started in immersive mode for the first time, Android displays a system dialog over it, telling the user about how to exit it. When running tests this is displayed over app UI and trying to dismiss it will cause test flakiness. It would be nice if TestButler could disable this dialog.

minSdkVersion

I need to support minSdkVersion 14. Would changing that minSdkVersion from 15 to 14 be doable?

TestButler doesn't play nice with Lollipop

I'm not sure what is going on with TestButler with Lollipop but really weird things happen with our app when it's installed. Most importantly, touch events don't seem to be triggered correctly by Espresso, but even when testing manually clicking buttons does fire the touch feedback but the listener code is never fired.
We're using ButterKnife @OnClick if that matters.
I haven't had time to look into the specifics of why this happens, but maybe it's worth creating this to keep track and see if anyone else has seen this problem

Cannot change developer settings after TestButler.setup()

We change the value of the "Don't keep activities" developer setting in between some tests. We use UI-Automator to navigate the developer options screen, find the "don't keep" cell, click on the switch, and then exit the developer options. After installing test-butler I noticed that when the test changed the setting via UI automator it wasn't "sticking". I set some debug breakpoints and through manipulating the UI manually while debugging I found that before we call TestButler.setup() I can go into the developer settings, change the value, exit, return to the developer settings, and I would find the value to still be set. But after I call TestButler.setup() and go through all that, the setting will no longer stick.

Is there anything with test-butler that would "lock" those developer settings? Is there any workaround?

Can't install on emulator with Google API

APK can be installed on the emulator with android-24 image, but the same emulator with Google API causes:
Failed to install test-butler-app-1.1.0.apk: Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Package couldn't be installed in /data/app/com.linkedin.android.testbutler-1: Package com.linkedin.android.testbutler has no signatures that match those in shared user android.uid.system; ignoring!]
Can this be fixed in any way? Platform 25 does not have images without Google API at this point.

Add a sample app

Adding a sample app module would provide a better example of integration and usage, as well as help facilitate testing changes to the project itself.

Unable to run test-butler-app

Hello,
I wish to deploy the test-butler-app onto my device. However, in Android Studio, the build shows it cannot run due to Default Activity not found.
screen shot 2017-03-09 at 3 56 07 pm

How can I get around this?

Gsm data switch

Disallow/allow data transfer from device by disabling/enabling gsm data transfer

Global locale changer

Could you please implement possibility of changing global locale like it is done in Custom Locale
app

It may be used in tests which use locale-dependent WebView

Support for Android Q (API 29)

TestButler 2.0.0 crashes with the following stacktrace when using it on the latest Android Q Beta (API 29):

2019-06-13 09:31:47.989 3682-3682/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.linkedin.android.testbutler, PID: 3682
java.lang.RuntimeException: Unable to create service com.linkedin.android.testbutler.ButlerService: java.lang.UnsupportedOperationException: Only apps can use the KeyguardLock API
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3950)
at android.app.ActivityThread.access$1500(ActivityThread.java:220)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1868)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7319)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)

java.lang.IllegalStateException: ButlerService is not started!

Hello, I have setup TestButler as specified except that the test that I am running was created with Espresso Recorder and I extended the class it created with AndroidJUnitRunner. I installed the TestButler .apk through the terminal with adb install. However when I attempt to use a test butler method within the espresso test I get the error mentioned above. Any help would be greatly appreciated. Thank you.

Example custom test runner crashes

The README.md states to do:

public class ExampleTestRunner extends AndroidJUnitRunner {
  @Override
  public void onStart() {
      TestButler.setup(ApplicationProvider.getApplicationContext());
      super.onStart();
  }

  @Override
  public void finish(int resultCode, Bundle results) {
      TestButler.teardown(ApplicationProvider.getApplicationContext());
      super.finish(resultCode, results);
  }
}

however, this crashed for me with androidX's test-core v1.0.0 with this:

java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
   at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
   at androidx.test.core.app.ApplicationProvider.getApplicationContext(ApplicationProvider.java:41)
   at my.custom.AndroidJUnitRunner.onStart(AndroidJUnitRunner.kt:11)
   at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2145)

so I figured this might be a race here that the registry doesn't know of the instrumentation yet. It is however totally unneccessary to use the registry at all, since the runner itself is the instrumentation that we need, so it is sufficient to do this:

public class ExampleTestRunner extends AndroidJUnitRunner {
  @Override
  public void onStart() {
      TestButler.setup(getTargetContext());
      super.onStart();
  }

  @Override
  public void finish(int resultCode, Bundle results) {
      TestButler.teardown(getTargetContext());
      super.finish(resultCode, results);
  }
}

This properly initialized TestButler for me, i.e. disabled animations, and ran my tests.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.