xcodebuild tests on a clone device - xcodebuild

I'm trying to run a simulator, amend it's appearance, set the status bar, and finally run tests on it.
# $UUID is an existing simulator in the CoreSimulator/Devices folder
$ Boot up an existing simulator
xcrun simctl boot $UUID
# Amend appearance to dark
xcrun simctl ui booted appearance "dark"
# Set status bar
xcrun simctl status_bar booted override --time "09:41" --cellularMode 'active' --operatorName 'Test'
This correctly boots up the right simulator with the correct amendments/status bar.
# Execute the test on the prepared simulator
xcodebuild -scheme $schemeName -project $projectName -derivedDataPath '/tmp/TestDerivedData/' -destination "platform=iOS Simulator,id=$UUID" build test
Unfortunately, xcodebuild creates a clone of the simulator, and runs the test on the clone:
SimDevice: Clone 1 of iPhone 8 Plus (463C36F0-2E89-4E51-B59A-4F8EB20F124C, iOS 13.4)
The cloned simulator does have the set appearance of the original simulator, but not the set status bar.
Question: can I prevent xcodebuild to spin up a clone and have it test on the prepared simulator? If not, can I modify the appearance of the cloned simulator before the test is run?

xcodebuild -disable-concurrent-destination-testing
This disables cloning.

Related

Can xcodebuild delete the contents of the project's Build Folder?

Back in Xcode 9, there was a build option called "Clean Build Folder..." (⌥⇧⌘K), which deleted all files in the build folder, only leaving the folder behind with no contents. Since then, this behavior was removed, the menu item's title changed to "Clean Build Folder", and now behaving like the old "Clean" used to.
xcodebuild has a build option called clean which simply does the same thing as Xcode's "Clean Build Folder" (⌘⇧K), which leaves stuff around.
Is there any way to delete all files in the build folder via a scriptable command?
What I've tried so far:
xcodebuild clean -workspace "My Workspace.xcworkspace" -scheme "My Scheme"
This, as I said, doesn't actually clean everything up. For that, I added this bodge to my build script:
export IS_XCODE_CACHE_FOLDER_PRESENT="`ls -la ~/Library/Developer/ | grep -x "Xcode"`"
if [ 0 -ne "$IS_XCODE_CACHE_FOLDER_PRESENT" ]; then
echo "Xcode cache folder should not be present at build time! Attempting to delete..."
rm -rf "~/Library/Developer/Xcode"
RM_RESULT=$?
if [ 0 -ne "$RM_RESULT" ]; then
echo "FAILED to remove Xcode cache folder!"
exit $RM_RESULT
fi
fi
I faced a similar requirement. So after trying for several hours, I resolved to a custom script instead of using Xcode's run script.
So instead of using Xcode to run the app on the simulator I use my script which in turn first cleans the build folder, then builds the project, then installs and finally launches the app in the simulator.
Here is what I am using as a quick script:
# Delete Build directory
rm -rf ./build/Build
# pod install
pod install
# Build project
xcrun xcodebuild -scheme Example -workspace Example.xcworkspace -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 11 Pro Max,OS=13.1' -derivedDataPath build
# Install App
xcrun simctl install "iPhone 11 Pro Max" ./build/Build/Products/Debug-iphonesimulator/Example.app/
# Launch in Simulator
xcrun simctl launch "iPhone 11 Pro Max" com.ihak.arpatech.Example
Note: See this question I posted to know the issue I was facing.
You can add clean action.
xcodebuild clean build -workspace "My Workspace.xcworkspace" -scheme "My Scheme"
see more in man xcodebuild
action ...
Specify one or more actions to perform. Available actions are:
build Build the target in the build root (SYMROOT). This is the default action, and is used if no action is given.
build-for-testing Build the target and associated tests in the build root (SYMROOT). This will also produce an xctestrun file in the build root. This requires speci-
fying a scheme.
analyze Build and analyze a target or scheme from the build root (SYMROOT). This requires specifying a scheme.
archive Archive a scheme from the build root (SYMROOT). This requires specifying a scheme.
test Test a scheme from the build root (SYMROOT). This requires specifying a scheme and optionally a destination.
test-without-building Test compiled bundles. If a scheme is provided with -scheme then the command finds bundles in the build root (SRCROOT). If an xctestrun file is
provided with -xctestrun then the command finds bundles at paths specified in the xctestrun file.
installsrc Copy the source of the project to the source root (SRCROOT).
install Build the target and install it into the target's installation directory in the distribution root (DSTROOT).
clean Remove build products and intermediate files from the build root (SYMROOT).

Haxe: openfl test works but not lime build

I'm in the process of moving all my projects to individual modules in IntelliJ rather than having one module in the entire git repo, and my IntelliJ builds stopped working. I notice it uses lime builds even though my module is set to openfl (and always has as far as I know)
openfl test flash -debug
this works
lime build GassyRickAstley.xml flash -debug -verbose
this does not. Full gist of both -v
Lime Command-Line Tools (2.9.1)
Initializing project...
Using project file: GassyRickAstley.xml
Warning: Could not read HXCPP config: /Users/booboo/.hxcpp_config.xml
Using target platform: FLASH
Running command: UPDATE
- Embedding asset: removed for brevity
- Copying template file: removed for brevity
Running command: BUILD
- Running command: haxe -main ApplicationMain -cp /usr/local/lib/haxe/lib/flixel/git -D flixel=4.3.0 -cp /usr/local/lib/haxe/lib/openfl/3,6,1 -D openfl=3.6.1 -cp /usr/local/lib/haxe/lib/lime/2,9,1 -D lime=2.9.1 -cp /usr/local/lib/haxe/lib/actuate/1,8,7 -D actuate=1.8.7 -cp /usr/local/lib/haxe/lib/ash/1,5,4/src -D ash=1.5.4 -cp source -cp lib -cp /usr/local/lib/haxe/lib/openfl/3,6,1/extern -cp ../Krakel/source -cp ../../lib/HxAssert/src -D native-trace -D HXCPP_QUIET -D openfl-next -D tools=2.9.1 -D flash-use-stage -D no-compilation -D openfl-flash -D verbose=1 -D web --macro flixel.system.macros.FlxDefines.run() -swf-lib export/flash/obj/assets.swf -swf-version 11.8 -swf export/flash/bin/GassyRickAstley.swf -cp export/flash/haxe -debug
georges-mbp:Gassy Rick Astley booboo$
It doesn't seem like anything went wrong, but I'm pretty shit with analyzing terminal output.
For now I can just build manually, but not having breakpoints is gonna get pretty lame, pretty fast. Any help is appreciated.
Bonus question. When I run/test the project in open fl and close the game's window the active terminal process never ends. I have to close the terminal, reopen and cd my directory again. is there a way around this?
It looks like it may have worked. openfl test flash is similar to running openfl build flash && openfl run flash, which in turn should behave practically the same as lime build flash && lime run flash.
I think your lime build flash command is working properly, but is exiting because the application has finished building. If you use lime test flash instead, it might build-and-run for you, as the other command does?

Universal framework using Xcode 8.3?

I'm trying to build universal swift framework. When I completed developing framework following several tutorials such as
https://medium.com/swiftindia/build-a-custom-universal-framework-on-ios-swift-549c084de7c8
Creating a universal framework using Xcode 8?
Also by using Aggregate target as well but fail to run in Simulator.
Note: I developed using Swift 3, Xcode Version 8.3
I tried with tutorials scripts too but fail.
Also my framework Xcode extension is xcodeproj.
My question is How to develop universal swift framework which will be release to client where he can test through Simulator as well as with real device?
Thanks in advance.
Edit: I followed this answer instruction and successfully build swift framework.
https://stackoverflow.com/a/26691080/614154
You can also use the following script. Supporting Swift and Simulator as well.
just add the content under Project Settings -> Build Phase as new Run Script Phase
Build Project
Folder will open, showing your zipped framework
https://gist.github.com/PaulEhrhardt/6d2be145c5d1b51c216914e7f032013e
#!/bin/sh
# iOS universal library build script supporting swift modules inclusive simulator slices
# prevention from running xcodebuild in a recusive way
if [ "true" == ${ALREADYINVOKED:-false} ]; then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"
# output directory for universal framework
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}/iOS"
# build both device and simulator versions for iOS
xcodebuild -project "${PROJECT_NAME}.xcodeproj" -scheme "${PROJECT_NAME}" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' ONLY_ACTIVE_ARCH=NO clean build
xcodebuild -project "${PROJECT_NAME}.xcodeproj" -scheme "${PROJECT_NAME}" -sdk iphoneos ONLY_ACTIVE_ARCH=NO clean build
# copy the framework structure from iphoneos build to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/iOS"
# copy existing Swift modules from iphonesimulator build to the universal framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/"
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/iOS/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# create universal binary file using lipo and place the combined executable in the universal framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/iOS/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
# intermediate step for copying the framework to the project's directory
mkdir -p "${TMPDIR}/${PROJECT_NAME}/Frameworks/iOS"
cp -R "${UNIVERSAL_OUTPUTFOLDER}/iOS/${PROJECT_NAME}.framework" "${TMPDIR}/${PROJECT_NAME}/Frameworks/iOS"
# create a zip file and move it to the project's directory
cd "${TMPDIR}/${PROJECT_NAME}/Frameworks/iOS"
zip -r "${PROJECT_NAME}.framework.zip" "${PROJECT_NAME}.framework"
mkdir -p "${PROJECT_DIR}/universal-framework"
mv "${PROJECT_NAME}.framework.zip" "${PROJECT_DIR}/universal-framework"
# optional: show the project's directory in Finder
open "${PROJECT_DIR}/universal-framework"
fi

xcodebuild far slower than Xcode?

Building from the command line with xcodebuild is orders of magnitude slower than building the same project, same scheme, same target from within Xcode. Does anyone know why this might be the case and how I might speed up my xcodebuild build?
I'm invoking xcodebuild as follows:
xcodebuild -scheme <SCHEME> -workspace <WORKSPACE> -configuration Debug -sdk iphonesimulator7.0 -jobs 12 build
for building on a 12-core Mac Pro. I guessed at the -jobs setting but it seems reasonable. Does anyone have any advice? Is there a way, by analyzing Xcode's build log, to tell what settings for xcodebuild most closely map to what Xcode itself is using? Thanks!
While this alone may not explain the slowness of xcodebuild compared to IDE, I've seen some improvements if I disable Spotlight indexing on ~/Library/Developer/Xcode/DerivedData directory.
When using xcodebuild test that will reboot the simulator each time. It is the main reason case the xcodebuild slowly. When you using xcode test directly, The simulator will not boot twice after booted.
You can try this:
xcodebuild -project Example.xcodeproj \
-scheme ExampleTests \
-disable-concurrent-destination-testing \
-destination 'platform=iOS Simulator,name=iPhone 13' \
-sdk iphonesimulator \
CODE_SIGNING_ALLOWED="NO" \
test
-disable-concurrent-destination-testing disable clone simulator in Xcode 14 and test in the same simulator
CODE_SIGNING_ALLOWED="NO" disable signing test target will faster

OCUnit Application Test with Simulator in terminal

Is it possible to start an application test that runs in the simulator with a terminal command(s)?
Thanks
Yes, I got it to work. My solution is somehow rough and might not be suitable in every case.
Disclaimer: This solution requires to edit system files. It works for
me, but may mess up XCode's unit testing stack, especially if you
do not understand what you are doing.
In /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Tools/RunPlatformUnitTests
replace
if [ "${TEST_HOST}" != "" ]; then
Warning ${LINENO} "Skipping tests; the iPhoneSimulator platform does not currently support application-hosted tests (TEST_HOST set)."
else
with
if [ "${TEST_HOST}" != "" ]; then
mkdir -p "${BUILT_PRODUCTS_DIR}/Documents"
mkdir -p "${BUILT_PRODUCTS_DIR}/Library/Caches"
mkdir -p "${BUILT_PRODUCTS_DIR}/Library/Preferences"
mkdir -p "${BUILT_PRODUCTS_DIR}/tmp"
export CFFIXED_USER_HOME="${BUILT_PRODUCTS_DIR}/"
RunTestsForApplication "${TEST_HOST}" "${TEST_BUNDLE_PATH}"
else
You may move the fixed user home to a different location, but I think you would need to move the .app and .octest bundles along.
Add -RegisterForSystemEvents to the OTHER_TEST_FLAGS build setting of your test bundle.
Make sure your test bundle contains a run script build phase with the contents
# Run the unit tests in this test bundle.
"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests"
Create a new scheme for your tests.
You should be able to run the tests from the command line using the standard xcodebuild:
xcodebuild -workspace $(WORKSPACE_NAME).xcworkspace -scheme $(TEST_SCHEME) -configuration debug -sdk iphonesimulator
The simulator must not be running, at the time you what to run the tests.
I hope this information is complete, if something doesn't work as expected please ask.
You can ensure that the Simulator isn't running with this:
osascript -e 'tell app "iPhone Simulator" to quit'
You can determine if the Simulator is active with this:
sh -c 'ps -xaco command | grep "iPhone Simulator"'
Worked perfectly, thanks!
Automated testing is back in action on our Jenkins CI-server!
Just had to fix my TEST_HOST=${BUNDLE_LOADER}. Do this if you get errors about "no such file" when running the tests.
It seems that with Xcode 4.5GM, running application tests in the simulator is now supported.