How does Xcode server run tests in release mode without Enable Testability? - ios

When using Xcode server to execute UI Tests, the bot has a setting to 'override' the configuration to Release mode.
This was handy as tests would be executed on release build.
Now when I am trying to run tests on TeamCity or CLI and pass the -configuration Release I get an error saying Module 'App name' was not compiled for testing
This can be solved by toggling Enable testability flag for Release configuration in build settings but that will have to be changed back each time before releasing the app.
Creating another build configuration is also not a desirable option as I have a lot of targets and maintaining an extra config for all would be a pain.
So how does Xcode server do this? Is there a CLI param or something I am missing? Or does it just change the setting via a prebuild script?

Related

iOS - How can I run unit/ui tests on Release scheme

I wonder if there is a way to run iOS AppTests and AppUITests on Release build. I found SO post here where OP mentioned,
However, the tests cannot run on the release build (because release
doesn't build for testing).
Seems he was unable to run tests in Release build. I am also getting some linking errors in Release build while testing but tests run fine on Debug build.
As mentioned in that answer, the code should be the same in release or debug mode. So unit tests should not require running in a release build, specifically.
For the UI tests, if this means your code has conditional compilation based on Release or Debug target, then you might be forced to test some end-to-end tests?
Option (ref)
Warning: Apple does not recommend doing this in the xcode release notes:
The Enable Testability build setting should be used only in your Debug configuration,
because it prohibits optimizations that depend on not exporting
internal symbols from the app or framework
In the project settings: Build Settings > Enable Testability
This will allow the #testable keyword to import the app in your test code.
Then edit the Test scheme to build the Release target

Xcode build issue with Jenkins job

I am building an iOS app and generating .app file in following two ways:
using Xcode in my machine
Jenkins job set up
In my Jenkins script, I am using the command xcodebuild -configuration "$CONFIGS" to generate the build. Where CONFIGS is set to one of my project configuration. Locally, I am building a scheme which is linked to same configuration.
Problem: .app generated from Jenkins build crashes as soon as I launch the app on certain iOS like 8.4.1; works on certain iOS versions like 7.X. Build generated from my local Xcode works fine on all supported iOS versions.
Diagnosis: On further troubleshooting and build size comparison I found that size of exec file inside .app file from Jenkins is half the size of file generated from my local machine.
Anyone has idea on why there could be size difference in executable files?
As you suspected, an architecture is missing in your app.
Check the Xcode configuration used by Jenkins, especially that the Build Settings Build active architecture only is on No, and that the Valid Architecture contains all the needed architecture (arm64 and armv7).
If you need to change something, do take care of the Debug vs. Release thing -- by default, building on your Mac usually yields a Debug build; it may not be the same on the Jenkins job.

How to dynamically change target for unit tests in Xcode 7?

I have a project that has multiple different targets/schemes (~38 of them as of writing this question) and I am trying to get unit testing working properly across all of the different targets. I got things working with one target, and tried adding my testing target to all of the different schemes, but it looks like when tests run for each scheme they actually run on the same, original target.
Looking in the project file I see that there's a specific Host Application associated with my testing target, and in the build settings the Bundle Loader and Test Host point to that same Host Application.
Is there any way to override those values for each scheme to run the tests against the current scheme's build target? Or some other way to set up a single test target to run across multiple build targets?
If you run the tests from the command line, or from an CI tool, like Jenkins, you can instruct xcodebuild to use the build settings that you provide. A simple usage example would be:
xcodebuild -scheme SomeScheme test TEST_HOST=target
You can control almost (if not any) build setting from Xcode, like code coverage generation, build directory, derived data directory, code sign identity, etc.
You can select the scheme when you run tests with Xcode server.
Look at WWDC 2014 continues integration talk for a walk through on how to set it up
https://developer.apple.com/videos/play/wwdc2014-415/
It's using Xcode 6 but it's very similar process to Xcode 7
Also check this CI(continues integration) guideline from apple
https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/adopt_continuous_integration.html
If anyone is wondering how to do that with UI tests (maybe it is working with unit tests, too), this is what I came up with:
First, we need to build the application which we are going to use to host our UI tests:
xcodebuild -scheme "<appSchemeName>" build -destination "<yourDestination>"
More info about destination parameter: https://mokacoding.com/blog/xcodebuild-destination-options/
Then, we need to run tests on our newly built application:
xcodebuild -scheme "<uiTestsSchemeName>" -destination "<yourDestination>" test TEST_TARGET_NAME="<yourNewlyBuiltAppTargetName>"
Destinations should match, since after the build .app is generated in your DerivedData folder, which will be used for UI tests hosting application

Crashlytics not uploading symbols in "Archive" mode

I managed to setup Crashlytics for an iOS app
Added ./Crashlytics.framework/run <uuid> as a post build step
Then my code uses [Crashlytics startWithAPIKey:<uuid> at startup.
So far it works works.
But since I have a script that changes the CFBundleVersion automatically for every single build, I decided to disable Crashlytics for debug builds, to avoid being spammed by development versions.
I followed these guidlines from the help pages, and changed my script to
releaseConfig="Release"
if [ "$releaseConfig" = "${CONFIGURATION}" ]; then
echo "Running Crashlytics"
./Crashlytics.framework/run {your_api_key_here}
fi
It works. The script only runs only when I use the "Archive" mode of Xcode 5, which is doing release builds.
However, unless I make a normal "Build", the version I archived does not appear in the Crashlytics dashboard, even when I make it crash with [Crashlytics crash] and wait for hours... But if I make a normal "Build" with the same CFBundleVersion, then suddenly my build appears in the dashboard, with all the crashes against the release build. (I know because I report the fact it's a release build with custom keys).
What so different between the "Archive" and "Build" mode? Is this a bug? Has any body managed to make a similar setup work with Crashlytics? What am I missing here?
I know this is an old question, but FYI, the scheme determines the configuration that gets built when archiving. Check your scheme and make sure it's building the "Release" configuration.

Mac OS X Server Xcode Bot Issue

I've successfully integrated CI on my Mac OS X server, but my bot actually build wrong.
I guess, that it should build archive with selected 'Release' Configuration, but it uses Debug configuration instead. Did someone faced with this?
The bot runs using configurations set the scheme it starts off of. If the scheme sets the archive configuration to Release, the bot should build in Release. Edit the scheme to archive in debug build configuration, and you should see your bot build an archive in debug build configuration.
The following shows the edit scheme window. This scheme's archive phase uses the release build config.
Hm, need to checkmark 'Perform Archive action' when creating/editing bot. This will cause performing Debug->Release Build configuration. If also check 'Perform Analyze/Test action' it will be: Debug->Analyze->Test->Archive.

Resources