instrumentation tests are executed with BUCK

Summary:Added ability to run instrumentation tests with BUCK.

This change uses BUCK to build and run instrumentation tests facebook style.
The gains are that we can execute the same tests internally at FB and in OSS.
Also running tests not via graddle:connect command is 1.5 minutes faster.

I'll keep keep an eye on stability Gradle and BUCK builds for a while.
Closes https://github.com/facebook/react-native/pull/6176

Differential Revision: D2999878

Pulled By: bestander

fb-gh-sync-id: d715ba231769e57100685a1256f2e530c589921c
shipit-source-id: d715ba231769e57100685a1256f2e530c589921c
This commit is contained in:
Konstantin Raev 2016-03-02 06:55:09 -08:00 committed by Facebook Github Bot 6
parent 4654b34c97
commit f827f7b79a
9 changed files with 123 additions and 83 deletions

View File

@ -224,7 +224,7 @@ android {
} }
buildConfigField 'boolean', 'IS_INTERNAL_BUILD', 'false' buildConfigField 'boolean', 'IS_INTERNAL_BUILD', 'false'
testApplicationId "com.facebook.react.tests" testApplicationId "com.facebook.react.tests.gradle"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.react.tests" package="com.facebook.react.tests.gradle"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0" > android:versionName="1.0" >
<uses-sdk android:targetSdkVersion="7" /> <uses-sdk android:targetSdkVersion="7" />
@ -12,8 +12,8 @@
<application> <application>
<activity <activity
android:name="com.facebook.react.testing.ReactAppTestActivity" android:name="com.facebook.react.testing.ReactAppTestActivity"
android:theme="@style/Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen" android:theme="@style/Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen"
/> />
</application> </application>
</manifest> </manifest>

View File

@ -1,66 +0,0 @@
include_defs('//ReactAndroid/DEFS')
CATALYST_PRIMERY_DEX_PATTERNS = [
'/CatalystAppShell^',
'/CatalystApplicationImpl^',
'^com/facebook/buck/android/support/exopackage/',
'/FbInstrumentationTestRunner^',
'/PrimaryDexFactories^',
'/Screenshot^',
'/DexmakerMockMaker^',
'/AndroidJUnitRunner^',
'/InstrumentationRunListener^',
'/ExposedInstrumentationApi^',
'/TestApplication^',
'/ApplicationWithInjector^',
'/RunListener^',
]
JS_BUNDLE_DEPS = [
#':intern-schema',
# '//java/com/facebook/graphql:schema',
# '//java/com/facebook/graphql/graphql-data:locate_node'
]
# instrumentation tests that will run for tests located in GitHub open sourced folder
android_binary (
name = 'react_oss',
manifest = 'AndroidManifest.xml',
keystore = '//keystores:debug',
use_split_dex = True,
linear_alloc_hard_limit = 10 * 1024 * 1024,
primary_dex_patterns = CATALYST_PRIMERY_DEX_PATTERNS,
deps = [
# ':integration_test_oss_bundle_js',
react_native_integration_tests_target('java/com/facebook/react/tests:tests'),
# '//java/com/facebook/catalyst/js/react-native-github/ReactAndroid/src/main/res:shell',
],
)
# Building this rule will produce a file named messenger_test.apk
android_instrumentation_apk(
name = 'react_oss_test_apk',
manifest = 'AndroidManifest.xml',
apk = ':react_oss',
deps = [
# react_native_integration_tests_target('java/com/facebook/react/tests:tests'),
# react_native_integration_tests_target('java/com/facebook/react/tests:tests'),
# '//java/com/facebook/catalyst:integration_test_oss_bundle_js#dev',
],
)
android_instrumentation_test(
name = 'react_oss_test',
apk = ':react_oss_test_apk',
)
sh_binary(
name = 'integration_test_oss_bundle_js',
main = 'buildBundle.sh',
# deps = [':InstallReactNativeNodeModules'],
visibility = ['PUBLIC'],
)

View File

@ -0,0 +1,5 @@
android_resource(
name = 'assets',
assets = '.',
visibility = ['PUBLIC'],
)

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.react.tests">
<supports-screens android:anyDensity="true" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- needed for screenshot tests -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
<uses-library android:name="android.test.runner" />
<activity
android:name="com.facebook.react.testing.ReactAppTestActivity"
android:theme="@style/Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen">
</activity>
</application>
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.facebook.react.tests"
android:label="Buck runs instrumentation tests"/>
</manifest>

View File

@ -0,0 +1,23 @@
include_defs('//ReactAndroid/DEFS')
# We are running instrumentation tests in simple mode: app code and instrumentation are in the same APK
# Currently you need to run these commands to execute tests:
#
# node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/assets/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
# gradle :ReactAndroid:packageReactNdkLibsForBuck
# buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests
# ./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests
android_binary(
name = 'instrumentation-tests',
manifest = 'AndroidManifest.xml',
keystore = '//keystores:debug',
deps = [
react_native_integration_tests_target('java/com/facebook/react/tests:tests'),
react_native_integration_tests_target('assets:assets'),
react_native_target('jni/prebuilt:reactnative-libs'),
react_native_target('jni/prebuilt:android-jsc'),
react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'),
react_native_target('java/com/facebook/react/devsupport:devsupport'),
],
)

View File

@ -1,4 +0,0 @@
#!/bin/bash
# TODO put output to temp folder?
node ./local-cli/cli.js bundle --entry-file ReactAndroid/src/androidTest/assets/TestBundle.js --dev --platform android --bundle-output ReactAndroid/src/androidTest/assets/ReactAndroidTestBundle.js

View File

@ -38,25 +38,29 @@ test:
# starting emulator in advance because it takes very long to boot # starting emulator in advance because it takes very long to boot
- $ANDROID_HOME/tools/emulator -avd testAVD -no-skin -no-audio -no-window: - $ANDROID_HOME/tools/emulator -avd testAVD -no-skin -no-audio -no-window:
background: true background: true
# assemble done separately because it requires quite a lot of memory and also gives time for emulator to load
- ./gradlew :ReactAndroid:assembleDebug -PdisablePreDex -Pjobs=1:
timeout: 360
- source scripts/circle-ci-android-setup.sh && waitForAVD - source scripts/circle-ci-android-setup.sh && waitForAVD
override: override:
# buck tests # build app
- buck/bin/buck test ReactAndroid/src/test/... --config build.threads=1
- buck/bin/buck build ReactAndroid/src/main/java/com/facebook/react - buck/bin/buck build ReactAndroid/src/main/java/com/facebook/react
- buck/bin/buck build ReactAndroid/src/main/java/com/facebook/react/shell - buck/bin/buck build ReactAndroid/src/main/java/com/facebook/react/shell
# temp, we can't run instrumentation tests yet
- buck/bin/buck build ReactAndroid/src/androidTest/java/com/facebook/react/tests
# unit tests # unit tests
- ./gradlew :ReactAndroid:testDebugUnitTest -PdisablePreDex - buck/bin/buck test ReactAndroid/src/test/... --config build.threads=1
# instrumentation tests
# compile native libs with Gradle script
- ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -PdisablePreDex -Pjobs=1:
timeout: 360
# build JS bundle for instrumentation tests # build JS bundle for instrumentation tests
- node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/assets/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js - node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/assets/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
# run tests on the emulator # build test APK
- buck/bin/buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
# run installed apk with tests
- ./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests
# Deprecated: run tests with Gradle, we keep them for a while to compare performance
- ./gradlew :ReactAndroid:testDebugUnitTest -PdisablePreDex
- ./gradlew :ReactAndroid:connectedAndroidTest -PdisablePreDex --stacktrace --info: - ./gradlew :ReactAndroid:connectedAndroidTest -PdisablePreDex --stacktrace --info:
timeout: 360 timeout: 360
@ -67,6 +71,8 @@ test:
- mkdir -p $CIRCLE_TEST_REPORTS/junit/ - mkdir -p $CIRCLE_TEST_REPORTS/junit/
- find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \; - find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
- find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \; - find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
# TODO circle does not understand Buck's report, maybe need to transform xml slightly
#- find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
deployment: deployment:
website: website:

View File

@ -0,0 +1,52 @@
#!/bin/bash
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH"
# clear the logs
adb logcat -c
# run tests and check output
python - $1 << END
import re
import subprocess as sp
import sys
import threading
import time
done = False
test_app = sys.argv[1]
def update():
# prevent CircleCI from killing the process for inactivity
while not done:
time.sleep(5)
print "Running in background. Waiting for 'adb' command reponse..."
t = threading.Thread(target=update)
t.dameon = True
t.start()
def run():
sp.Popen(['adb', 'wait-for-device']).communicate()
p = sp.Popen('adb shell am instrument -w %s/android.support.test.runner.AndroidJUnitRunner' % test_app,
shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE)
return p.communicate()
success = re.compile(r'OK \(\d+ tests\)')
stdout, stderr = run()
done = True
print stderr
print stdout
if success.search(stderr + stdout):
sys.exit(0)
else:
# dump the logs
sp.Popen(['adb', 'logcat', '-d']).communicate()
sys.exit(1) # make sure we fail if the test failed
END
RETVAL=$?
exit $RETVAL