Runscript condition to skip Test Target - ios

"${PODS_ROOT}/SwiftLint/swiftlint"
Using swift lint in main target. Would like to disable it while running UI automation testing targets. Is there any condition or straight forward way to restrict while the automation target is running?
Tried target name check
if [[ "${TARGET_NAME}" == "" ]]; then
and custom flags too, didnt help.

Related

How do I pass preprocessor macro name in xcode build command?

I am doing CI build on azure devops. I am wondering how to pass pre-processor macro value so that I can make different flavours of build.
AFAIK if we can set preprocessor macro in xcode build then we can do it on azure devops as well.
Any helpful pointer is welcome
Approach 1: By the means of GCC_PREPROCESSOR_DEFINITIONS
You have to make use of GCC_PREPROCESSOR_DEFINITIONS on xcodebuild command line.
Here is a sample macro in your code
#ifdef Flavour1
NSLog(#"This is flavour 1");
#endif
and Here is how you pass the macro through command line
xcodebuild -verbose -scheme "YourAppScheme" GCC_PREPROCESSOR_DEFINITIONS='$GCC_PREPROCESSOR_DEFINITIONS Flavour1=1'
Approach 2: By the means of separate xcode Scheme
Have a scheme and it's respective target for each flavour. so that it can have different App name,version number,signers etc if required and you can have macro injected in preprocessor definition of build settings in target.
All you have to do is just pass the right scheme in xcodebuild command and that's you sorted
P.S:-
I personally prefer Approach 2 because it's easy to customise without worrying much about xcodebuild command line parameters.
You can create a ruby script which can setup the project. Xcodeproj is a powerful tool to modify Xcode projects.
https://github.com/CocoaPods/Xcodeproj

Specify individual target build settings with xcodebuild

I have an iOS app that uses Cocoapods, and has a local cocoa touch framework target, and I'm running into an issue with specifying build settings in the command line using xcodebuild.
I understand that you can specify build settings like PROVISIONING_PROFILE, CODE_SIGN_IDENTITY, and DEVELOPMENT_TEAM by appending their key=value pair to the end of the command.
However those setting appear to be applied to the entire project, but I only need them to apply to the app target since touch frameworks cannot be signed.
How do I specify build settings for an individual target using xcodebuild? If it cannot be done using xcodebuild, could this be accomplished using fastlane?
Use schemes. You can set the scheme to build/archive with a particular build configuration and executable.

Testing two targets with same tests

I had a project with 3 targets:
The app target
Unit tests target (host app >> 1.)
UI tests target (target app >> 1.)
Now, after I added a new app target for a different branding (with slight changes):
The app target
The new app (new branding)
Unit tests target (host app >> 1.)
UI tests target (target app >> 1.)
I realised that the unit and UI tests have specific target applications. For the new app, 90% of the tests will be the same. Is there a way to setup the test targets to run twice, once for each of my apps/brandings? (maybe with extern tools?)
After some time I found out that what I needed was different targets.
These are my targets now:
The app target
The new app (new branding)
Unit tests target (host app >> 1.)
UI tests target (target app >> 1.)
Unit tests target (host app >> 2.)
UI tests target (target app >> 2.)
To run the tests (or any subset of tests) twice against different apps, you will need two schemes, and you will need to invoke them separately.
If you want this to be a single-action process, create one scheme for each target app with the correct tests selected to run, then create a shell script that runs tests for those two schemes, one after the other. Then you can just run the script to have tests run against both apps.
To simplify the xcodebuild command, you can use Scan, and to automate the process, you can use Jenkins to run your script on a regular basis, or on triggers like a new commit being pushed to your repository.
Scan works nicely with multiple schemes - add them both to the Scanfile and then have your shell script run them sequentially. In Ruby:
`scan --scheme "SchemeOne"`
`scan --scheme "SchemeTwo"`
As Daniel stated you can use the same files in 2 different test targets. I am attempting this now, I will let you know how it goes. I found the info at the tutorial below:
Tutorial on using same files from 2 test targets

Build os x tool as part of iOS project without breaking xcodebuild archive?

Each time I build my iOS project, I'd like to it also build a couple OS X projects. These are command line tools. I don't care if they're included in the Archive, I just want to make sure they compile correctly each and every time.
They're little command line tools for specific tasks which access the same libraries. In the past, I've built these far less frequently and as a result they suffer from code rot. I'd like to build them each time I build the iOS project, even when I just Build in Xcode.
To do this, I tried dragging the projects into my iOS project and set them as dependancies.
This works fine in the IDE, but when I try to build via xcodebuild:
xcrun xcodebuild -sdk iphoneos -workspace AppName.xcworkspace \
-scheme AppName archive
I get an error that looks like this:
=== BUILD TARGET dslfi OF PROJECT dslfi WITH CONFIGURATION Release ===
Check dependencies
target specifies product type 'com.apple.product-type.tool', but there's no such
product type for the 'iphoneos' platform
** ARCHIVE FAILED **
The following build commands failed:
Check dependencies
(1 failure)
Is there any way to continue to build these each time I build while still satisfying xcodebuild?
You can add any number of targets (iOS app, static lib, contole app, etc) into same project.
Then you should create another target -
Then you have options:
3.1 Go to scheme settings for aggregate target and add other targets:
where you can specify actions you want to perform on certain target
3.2 You may pick aggregate target and go to build settings and add other targets as a dependencies for this target.
Option 3.1 seems to be the one you need: you can add as many targets as you wish to be build. And you can specify another target for running.
So you'll have something like:
targets:
target 1 - iOS app
target 2 - other app
target 3 - other app
target 4 - aggregate target
scheme configuration for target 4
build section:
target 1
target 2
target 3
run section:
executable: target 1 (iOS app)
Once this is completed you may use your scheme to do builds
xcodebuild -scheme your_scheme [...other options...] archive
UPDATE
You can skip creation of aggregate target.
You can directly create new scheme and to the configuration you want without involving aggregate target.
UPDATE 2
Make sure to share your scheme to be able to keep it in source control.
UPDATE 3
The option w/o aggregate target is more preferable way to achieve this in case if your targets are not depend on each other directly (as far as I understand you). This is the main purpose for schemes.
A scheme is a collection of settings that specify which targets to
build, what build configuration to use, and the executable environment
to use when the product specified by the target is launched. When you
open an existing project (or create a new one), Xcode automatically
creates a scheme for each target.

Passing compiler flags through xcodebuild

I'm currently using xcodebuild to automate testing for iOS.
Right now, I'm stuck on trying to pass compiler flags through Xcode directly to the compiler. These flags are: -fprofile-arcs -ftest-coverage.
I don't have the liberty of modifying the xcodeproj, that's why I want to inject these flags via the xcodebuild command.
It would be something like:
xcodebuild -project path/to/my.xcodeproj -scheme MyApp -fprofile-arcs -ftest-coverage
Is that feasible? How?
Apparently most compiler flags can be expressed as constants, and these can be passed to the compiler via xcodebuild easily.
To get them, simply select the option in the xcode build settings view, and hit command-C (copy). In my case, they were GCC_GENERATE_TEST_COVERAGE_FILES and GCC_INSTRUMENT_PROGRAM_FLOW_ARCS.
My command roughly looks like this:
xcodebuild GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES ...
To set compiler flags with xcodebuild, you need to put them in the OTHERCFLAGS option.
For example:
xcodebuild -project path/to/my.xcodeproj -scheme MyApp \
OTHERCFLAGS="-fprofile-arcs -ftest-coverage"
Yes, all of the compiler setting actually boils down to string key-value pairs. I answered a very similar question about setting preprocessor macros from the command line that is just as applicable to these settings you would like to set:
Setting a #define from the command line in xcode 4.6
I would also like to call attention to the use of ${inherited} -- using this values allows you to use the Xcode project-specified values AND append your own. Documentation for each of the build settings including those that you located via copy-paste can be found here:
http://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html
Glad you were able to get it to work -- now you can really make xcodebuild do even more for you without requiring changes of the target Xcode project!

Resources