This question is related to the previous ones: Codename One - Test Recorder: execute a test on a real device and Codename One - tests.dat file needed when using build.unitTest=1
My "test-for-ios-device" and "test-for-android-device" ant tasks produces IPAs and APKs that don't run any tests (actually the build server generates a .bin file that I rename to .ipa). Instead my tests work correctly in the Codename One Simulator. The tests are not trivial and all the logs plus one screenshot are sent to me by e-mail automatically during the test (using the Simulator), and I receive the report by e-mail without problems. Instead on real devices nothing happens.
I report the build.xml (I removed some irrilevant tasks in this copy) and the logs of Samsung Galaxy S6 and iPhone8.
<?xml version="1.0" encoding="UTF-8"?>
<!--build_version=3.7-->
<!--
This build script was generated by Codename One to build native mobile applications using Java.
To learn more about Codename One go to https://www.codenameone.com/
-->
<project name="Myapp" default="default" basedir=".">
<description>Builds, tests, and runs the project Myapp.</description>
<import file="nbproject/build-impl.xml"/>
<property file="codenameone_settings.properties"/>
<property name="automated" value="false" />
<taskdef name="codeNameOne" classname="com.codename1.build.client.CodeNameOneBuildTask" classpath="CodeNameOneBuildClient.jar"/>
<taskdef name="prepareTests" classname="com.codename1.build.client.PrepareTestsTask" classpath="CodeNameOneBuildClient.jar"/>
<taskdef name="installLibs" classname="com.codename1.build.client.InstallLibsTask" classpath="CodeNameOneBuildClient.jar"/>
<taskdef name="verifyDir" classname="com.codename1.build.client.VerifyDir" classpath="CodeNameOneBuildClient.jar"/>
<taskdef name="generateGuiSources" classname="com.codename1.build.client.GenerateGuiSources" classpath="CodeNameOneBuildClient.jar"/>
<taskdef name="initOfflineBuilder" classname="com.codename1.build.client.InitOfflineBuilder" classpath="CodeNameOneBuildClient.jar"/>
<target depends="init,compile,jar" name="compile-test">
<mkdir dir="${build.test.classes.dir}" />
<mkdir dir="${test.src.dir}" />
<javac destdir="${build.test.classes.dir}"
encoding="${source.encoding}"
source="1.8"
target="1.8"
bootclasspath="CLDC11.jar" excludes="${excludes}"
classpath="${javac.classpath}:${build.classes.dir}">
<src path="${test.src.dir}"/>
</javac>
<prepareTests classesDir="${build.classes.dir}" testClassesDir="${build.test.classes.dir}" seJar="JavaSE.jar" metaDataFile="${build.test.classes.dir}/tests.dat" />
<jar jarfile="dist/unitTests.jar">
<fileset dir="${build.classes.dir}"/>
<fileset dir="${build.test.classes.dir}"/>
<fileset dir="lib/impl/cls"/>
</jar>
</target>
<target depends="compile-test" name="-do-test-run">
<!-- JavaSE.jar is added here since the test execution might fail otherwise for a pre-existing project -->
<java classpath="dist/unitTests.jar:${javac.test.classpath}:${file.reference.JavaSE.jar}" classname="com.codename1.impl.javase.TestRunner" fork="true">
<arg value="${codename1.packageName}.${codename1.mainName}" />
</java>
</target>
<target depends="-do-test-run" description="Run unit tests." name="test"/>
<target name="-pre-compile">
<echo>Compile is forcing compliance to the supported API's/features for maximum device compatibility. This allows smaller
code size and wider device support</echo>
<mkdir dir="build/tmp"/>
<javac destdir="build/tmp"
encoding="${source.encoding}"
source="1.8"
target="1.8"
bootclasspath="lib/CLDC11.jar" excludes="${excludes}"
classpath="${javac.classpath}:${build.classes.dir}">
<src path="${src.dir}"/>
</javac>
</target>
<target name="-post-compile">
<delete>
<fileset dir="${build.classes.dir}" includes="**/package-info.class"/>
</delete>
<delete>
<fileset dir="${build.classes.dir}" includes="**/package-info.class"/>
</delete>
<delete>
<fileset dir="${build.classes.dir}" includes="**/Thumbs.db"/>
</delete>
</target>
<target name="build-for-ios-device" depends="clean,copy-ios-override,copy-libs,jar,clean-override">
<codeNameOne
jarFile="${dist.jar}"
displayName="${codename1.displayName}"
packageName = "${codename1.packageName}"
mainClassName = "${codename1.mainName}"
version="${codename1.version}"
icon="${codename1.icon}"
vendor="${codename1.vendor}"
subtitle="${codename1.secondaryTitle}"
targetType="iphone"
certificate="${codename1.ios.debug.certificate}"
certPassword="${codename1.ios.debug.certificatePassword}"
provisioningProfile="${codename1.ios.debug.provision}"
appid="${codename1.ios.appid}"
automated="${automated}"
/>
</target>
<target name="test-for-ios-device" depends="clean,copy-ios-override,copy-libs,compile-test,clean-override">
<codeNameOne
jarFile="dist/unitTests.jar"
displayName="${codename1.displayName}"
packageName = "${codename1.packageName}"
mainClassName = "${codename1.mainName}"
version="${codename1.version}"
icon="${codename1.icon}"
vendor="${codename1.vendor}"
subtitle="${codename1.secondaryTitle}"
buildArgs="build.unitTest=1"
targetType="iphone"
certificate="${codename1.ios.debug.certificate}"
certPassword="${codename1.ios.debug.certificatePassword}"
provisioningProfile="${codename1.ios.debug.provision}"
appid="${codename1.ios.appid}"
automated="${automated}"
/>
</target>
<target name="test-for-android-device" depends="clean,copy-android-override,copy-libs,compile-test,clean-override">
<codeNameOne
jarFile="dist/unitTests.jar"
displayName="${codename1.displayName}"
packageName = "${codename1.packageName}"
mainClassName = "${codename1.mainName}"
version="${codename1.version}"
icon="${codename1.icon}"
vendor="${codename1.vendor}"
subtitle="${codename1.secondaryTitle}"
buildArgs="build.unitTest=1"
targetType="android"
keystoreAlias="${codename1.android.keystoreAlias}"
keystore="${codename1.android.keystore}"
certPassword="${codename1.android.keystorePassword}"
automated="${automated}"
/>
</target>
<target name="build-for-ios-device-release" depends="clean,copy-ios-override,copy-libs,jar,clean-override">
<codeNameOne
jarFile="${dist.jar}"
displayName="${codename1.displayName}"
packageName = "${codename1.packageName}"
mainClassName = "${codename1.mainName}"
version="${codename1.version}"
icon="${codename1.icon}"
vendor="${codename1.vendor}"
subtitle="${codename1.secondaryTitle}"
appStoreBuild="true"
production="true"
targetType="iphone"
certificate="${codename1.ios.release.certificate}"
certPassword="${codename1.ios.release.certificatePassword}"
provisioningProfile="${codename1.ios.release.provision}"
appid="${codename1.ios.appid}"
automated="${automated}"
/>
</target>
<target name="copy-libs" depends="init">
<copy todir="${build.classes.dir}">
<fileset dir="lib/impl/cls" />
</copy>
</target>
<target name="copy-android-override">
<mkdir dir="${build.classes.dir}" />
<mkdir dir="override" />
<copy todir="${build.classes.dir}">
<fileset dir="override" includes="**/*_android.ovr"/>
<fileset dir="override" includes="**/*_android-phone.ovr"/>
<fileset dir="override" includes="**/*_android-tab.ovr"/>
<fileset dir="override" includes="**/*_phone.ovr"/>
<fileset dir="override" includes="**/*_tablet.ovr"/>
</copy>
<copy todir="${build.classes.dir}">
<fileset dir="native/android" includes="**/*"/>
<fileset dir="lib/impl/native/android" includes="**/*"/>
</copy>
</target>
<target name="copy-ios-override">
<mkdir dir="${build.classes.dir}" />
<mkdir dir="override" />
<copy todir="${build.classes.dir}">
<fileset dir="override" includes="**/*_ios.ovr"/>
<fileset dir="override" includes="**/*_iphone.ovr"/>
<fileset dir="override" includes="**/*_ipad.ovr"/>
<fileset dir="override" includes="**/*_phone.ovr"/>
<fileset dir="override" includes="**/*_tablet.ovr"/>
</copy>
<copy todir="${build.classes.dir}">
<fileset dir="native/ios" includes="**/*"/>
<fileset dir="lib/impl/native/ios" includes="**/*"/>
</copy>
</target>
<target name="clean-override">
<delete>
<fileset dir="${build.classes.dir}" includes="**/*.ovr"/>
<fileset dir="${build.classes.dir}" includes="**/*.java"/>
<fileset dir="${build.classes.dir}" includes="**/*.m"/>
<fileset dir="${build.classes.dir}" includes="**/*.h"/>
</delete>
</target>
<target name="build-for-android-device" depends="clean,copy-android-override,copy-libs,jar,clean-override">
<codeNameOne
jarFile="${dist.jar}"
displayName="${codename1.displayName}"
packageName = "${codename1.packageName}"
mainClassName = "${codename1.mainName}"
version="${codename1.version}"
icon="${codename1.icon}"
vendor="${codename1.vendor}"
subtitle="${codename1.secondaryTitle}"
targetType="android"
keystoreAlias="${codename1.android.keystoreAlias}"
keystore="${codename1.android.keystore}"
certPassword="${codename1.android.keystorePassword}"
automated="${automated}"
/>
</target>
<target name="-pre-init">
<property name="application.args" value="${codename1.packageName}.${codename1.mainName}"/>
<property name="javac.source" value="1.8" />
<property name="javac.target" value="1.8" />
<mkdir dir="native/javase" />
<mkdir dir="native/android" />
<mkdir dir="native/internal_tmp" />
<mkdir dir="native/ios" />
<mkdir dir="native/j2me" />
<mkdir dir="native/rim" />
<mkdir dir="native/win" />
<mkdir dir="native/javascript" />
<mkdir dir="lib/impl/cls" />
<mkdir dir="lib/impl/stubs" />
<mkdir dir="lib/impl/native" />
<mkdir dir="lib/impl/native/android" />
<mkdir dir="lib/impl/native/ios" />
<mkdir dir="lib/impl/native/j2me" />
<mkdir dir="lib/impl/native/rim" />
<mkdir dir="lib/impl/native/win" />
<mkdir dir="lib/impl/native/javascript" />
<installLibs lib="lib" dest="lib/impl" />
<generateGuiSources srcDir="src" encoding="UTF-8" guiDir="res/guibuilder" />
</target>
<target name="-post-jar">
<mkdir dir="native/javase" />
<mkdir dir="native/internal_tmp" />
<mkdir dir="lib/impl/native/javase" />
<javac destdir="native/internal_tmp"
encoding="${source.encoding}"
source="1.8"
target="1.8"
bootclasspath="CLDC11.jar" excludes="${excludes}"
classpath="${javac.classpath}:${build.classes.dir}">
<src path="native/javase"/>
<src path="lib/impl/native/javase"/>
</javac>
</target>
<target name="-post-clean" depends="refresh-libs-impl">
</target>
<target name="refresh-libs" depends="refresh-libs-impl,jar">
</target>
<target name="refresh-libs-impl">
<delete dir="lib/impl" />
<installLibs lib="lib" dest="lib/impl" />
</target>
</project>
Samsung Galaxy S6 (only the relevant part of the log):
-----STARTING TESTS-----
> 12-08 13:19:05.751 D/Myapp( 6834): [EDT] 0:0:0,10 - Failed to create instance of cool.myapp.app.tests.LoginPageTest
> 12-08 13:19:05.751 D/Myapp( 6834): [EDT] 0:0:0,10 - Verify the class is public and doesn't have a specialized constructor
> 12-08 13:19:05.751 D/Myapp( 6834): [EDT] 0:0:0,11 - Exception: java.lang.ClassNotFoundException - cool.myapp.app.tests.LoginPageTest
> 12-08 13:19:05.751 W/System.err( 6834): java.lang.ClassNotFoundException: cool.myapp.app.tests.LoginPageTest
Note that LoginPageTest is public and without any constructor defined by me.
iPhone 8:
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(libAccessibility.dylib)[35170] <Notice>: Retrieving resting unlock: 0
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(FrontBoardServices)[35170] <Notice>: [FBDisplayManager=0x1d404b1f0] silently connecting <FBSDisplayConfiguration: 0x1d4177e80; Main; mode: "375x667@2x 60Hz p3"> {
> CADisplay.name = LCD;
> CADisplay.deviceName = primary;
> CADisplay.seed = 2;
> tags = 0;
> currentMode = <FBSDisplayMode: 0x1d4268140; 375x667@2x (750x1334/2) 60Hz p3>;
> safeOverscanRatio = {0.89999997615814209, 0.89999997615814209};
> nativeCenter = {375, 667};
> pixelSize = {750, 1334};
> bounds = {{0, 0}, {375, 667}};
> CADisplay = <CADisplay:LCD primary>;
> }
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(UserNotifications)[35170] <Notice>: [cool.myapp.app] Setting badge number to 0
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(UserNotifications)[35170] <Notice>: [cool.myapp.app] Set badge number [ hasCompletionHandler: 0 hasError: 0 ]
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(HangTracer)[35170] <Notice>: refreshPreferences: HangTracerEnabled: 0
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(HangTracer)[35170] <Notice>: refreshPreferences: HangTracerDuration: 500
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(HangTracer)[35170] <Notice>: refreshPreferences: ActivationLoggingEnabled: 0 ActivationLoggingTaskedOffByDA:0
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(UserNotifications)[35170] <Notice>: [cool.myapp.app] Setting badge number to 0
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(UserNotifications)[35170] <Notice>: [cool.myapp.app] Set badge number [ hasCompletionHandler: 0 hasError: 0 ]
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(CoreGraphics)[35170] <Error>: CGContextSetAllowsAntialiasing: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
> Dec 8 13:26:35 iPhone CodenameOneUnitTestExecutor(UIAccessibility)[35170] <Notice>: loading ax info now. wasCoalesced: 1
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC Enabling TLS [1:0x1d4366840]
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TCP Conn Start [1:0x1d4366840]
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: Task <1F77BFCA-1D0F-42ED-BAE8-4E0A54D579F7>.<0> setting up Connection 1
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: Sending CFNA PAC query
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: Received CFNA PAC response
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TCP Conn Connected [1:0x1d4366840]: Err(16)
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TCP Conn Event [1:0x1d4366840]: 1
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC Enabling TLS [1:0x1d4366840]
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Event [1:0x1d4366840]: 1, Pending(0)
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(UIAccessibility)[35170] <Notice>: loading ax info now. wasCoalesced: 1
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Event [1:0x1d4366840]: 2, Pending(0)
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(libboringssl.dylib)[35170] <Error>: Function boringssl_context_get_peer_sct_list: line 1754 received sct extension length is less than sct data length
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Event [1:0x1d4366840]: 11, Pending(0)
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Event [1:0x1d4366840]: 12, Pending(0)
> Dec 8 13:26:36 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Event [1:0x1d4366840]: 14, Pending(0)
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Trust Result [1:0x1d4366840]: 0
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Event [1:0x1d4366840]: 20, Pending(0)
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TCP Conn Event [1:0x1d4366840]: 8
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: TIC TLS Handshake Complete [1:0x1d4366840]
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: Task <1F77BFCA-1D0F-42ED-BAE8-4E0A54D579F7>.<0> now using Connection 1
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: Task <1F77BFCA-1D0F-42ED-BAE8-4E0A54D579F7>.<0> sent request, body N
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: Task <1F77BFCA-1D0F-42ED-BAE8-4E0A54D579F7>.<0> received response, status 200 content K
> Dec 8 13:26:37 iPhone CodenameOneUnitTestExecutor(CFNetwork)[35170] <Notice>: Task <1F77BFCA-1D0F-42ED-BAE8-4E0A54D579F7>.<0> response ended