Search code examples
xcodexcodebuildxcode-projectxcodeproj

Is there a way to autocreate schemes for a Xcode Project from command line


I'm tryging to configure a CI pipeline and run unit tests automatically, but I'm handling with no schemes for the current workspace. I know I can create them by using Xcode/ Manage Schemes etc... but since the nature it self of the automation in the tests routine, I'm figuring out if there's a way to automatize the scheme creation step.


Solution

  • Firstly to test an Xcode project is mandatory to use at least one scheme configured to run tests. After that the test should be ran from command line with xcodebuild. So there was two steps to fulfill, first automatically generate the schemes required, and secondly run the tests for the test-configured-schemes.

    1- By using a ruby gem CocoaPods/Xcodeproj in a script I was able to perform the creation of the schemes. The following code creates the schemes for all targets:

    #!/usr/bin/env ruby
    # fix_schemes.rb
    
    require 'xcodeproj'
    project_path = '/your_path/your_project.xcodeproj'
    project = Xcodeproj::Project.open(project_path)
    

    Step 1 (OK)

    2- Create a shell script to run the tests from command line. This script receives can be edited to include the scheme(s) in which the tests must run, looping scheme by scheme until all tests pass or one fail.

    #!/bin/bash
    #!/bin/bash -e
    # build-test.sh
    
    # Set bash script to exit immediately if any commands fail.
    set -e
    
    ## declare the schemes to test
    declare -a arr=("Scheme01UnitTests" "Scheme02UnitTests")
    
    ## Parameters
    ## -s The SDK to use (iphoneos, iphonesimulator) default "iphonesimulator"
    ## -o The simulator Operating System, default 11.2
    ## -c Configuration (Debug, Release), default Debug
    
    
    SDK="iphonesimulator"
    OS=11.2
    CONFIG="Debug"
    
    #Parsing arguments
    while getopts "s:o:c:" option; do
      case $option in
        s ) SDK=$OPTARG
        ;;
        o ) OS=${OPTARG}
        ;;
        c ) CONFIG=${OPTARG}
        ;;
      esac
    done
    
    echo "Using OS: $OS"
    echo "Using SDK: $SDK"
    echo "Using Configuration: $CONFIG"
    
    ## now loop through the above array
    for s in "${arr[@]}"
        do
            echo "***************************************"
            echo "**   Test $s"
            echo "***************************************"
            cmd="set -o pipefail && env \"NSUnbufferedIO=YES\" xcodebuild -workspace MyWorkspace.xcworkspace -scheme $s -sdk $SDK -destination 'platform=iOS Simulator,name=iPhone 6s,OS=$OS' -configuration $CONFIG test | xcpretty -r junit --no-color -o 'build/reports/TEST-${s}.xml'"
    
            eval $cmd
        done
    exit 0;
    

    Step 2 (OK)

    Hope this helps!