Running tests for Swift package using xcodebuild: Error tests must be run on a concrete device

Viewed 1893

I am trying to run tests for my Swift package (defined by Package.swift) by using xcodebuild:

xcodebuild -scheme "package-name-Package" -configuration "Debug" -sdk "iphonesimulator14.5" -arch "x86_64" test`

Unfortunately, I keep getting this error:

xcodebuild: error: Failed to build workspace package-name with scheme package-name-Package.
    Reason: Cannot test target “Target1Tests” on “Any iOS Simulator Device”: Tests must be run on a concrete device
Cannot test target “Target2Tests” on “Any iOS Simulator Device”: Tests must be run on a concrete device
Cannot test target “Target3Tests” on “Any iOS Simulator Device”: Tests must be run on a concrete device

I'm not sure what -sdk to use. I've read the output of xcodebuild -showsdks and chosen appropriately (I need to build/ test for iOS). I've tried iphoneos iphonesimulator, iphoneos15.0, iphonesimulator15.0, iphonesimulator14.5, iphoneos14.5 as the sdk. (both Xcode 12 and Xcode 13 beta, by using xcode-select)

1 Answers

Thanks for the upvote kind stranger, I did manage to figure it out: There are 2 ways.

The main solution is to use -destination instead of -sdk. Okay, _dump:

Swift Package inside an Xcode Workspace (WorkspaceName.xcworkspace)

My preferred option: I ended up putting the Swift Package in an Xcode workspace. By this I mean dragging the root directory containing the Swift Package (and also the Workspace) into the Xcode project navigator/ workspace.

The advantage is the Xcode schemes are not generated every time you launch Xcode, but are associated with the workspace instead. This means your modifications are not reset every time you launch Xcode (e.g. adding environment variables).

xcodebuild -workspace ./WorkspaceName.xcworkspace -scheme SchemeName -destination 'platform=iOS Simulator,name=iPhone 12' test

Notes:

  • If you want to build the project, just set the correct scheme and replace test with build
  • Here is a list of destinations available on Xcode 13 Beta. An example is: { platform:iOS Simulator, id:FD90A730-A1D5-4BBC-B61A-0324400EE9EA, OS:15.0, name:iPhone 12 }
  • you can get SchemeName from the Xcode workspace or by running xcodebuild -list
  • The destination used is platform=iOS Simulator,name=iPhone 12. You can get a list of destinations from xcodebuild -workspace ./WorkspaceName.xcworkspace -scheme SchemeName -showdestinations in a directory that contains an Xcode project, workspace or package.
  • I got it working by just selecting the platform and name properties, without specifying OS or `ID. This is nice because the CI system might right a different Xcode with different OS, though you might prefer to specify it.
  • You need to format the destination correctly, xcodebuild prints them out in json, but you should provide them in comma separated with equals signs.

Swift Package without an Xcode Workspace

If you don't have a workspace, you can do:

  • Run xcodebuild -list
  • Pick the scheme that makes the most sense (probably the scheme that says your-package-name-is-here-Package)
  • Run:
xcodebuild -scheme SchemeName -destination 'platform=iOS Simulator,name=iPhone 12' test
  • Caveat: Actually make sure you don't have a workspace in the same directory. (i.e. one that doesn't contain your Swift Package, because Xcode gets confused.) If it sees a workspace, it won't detect the autogenerated Xcode schemes based on the Package.swift in the current directory.
Related