Can I test a package without building every single target?

Objective

I am looking to run tests defined in a test target by exclusively building the test target and its declared dependencies. This means skipping targets not explicitly defined as dependencies in that test target's definition.

Context

Given the following Package.swift:

let package = Package(
    name: "MyPackage",
    products: [
        // We define a single product that depends on a single target.
        .library(name: "MyPackage", targets: ["MyPackage"]),
    ],
    dependencies: [
        // This dependency is not supported on the target platform.
        .package(url: "dependency", from: "1.0.0"),
    ],
    targets: [
        // I am looking to build only these two:
        .target(name: "MyPackage", dependencies: []),
        .testTarget(name: "MyPackageTests", dependencies: ["MyPackage"]),

        // This executable target is the only one with the unsupported dependency.
        .executableTarget(name: "Unsupported", dependencies: [
            "MyPackage", 
            .product(name: "Dependency", package: "dependency")
        ]),
    ]
)

I want to run the tests in the MyPackageTests target without building the Unsupported target, since the dependency package won't build on my platform.

Things I've Tried

$ swift build --target MyPackageTests
$ swift test --skip-build

[...]
Failure: No test bundle found at path `/Users/user/MyPackage/.build/arm64-apple-macosx/debug/MyPackagePackageTests.xctest`
[...] (full error available on request)
$ swift build --target MyPackageTests
$ swift test --test-product MyPackageTests
error: no tests found; create a target in the 'Tests' directory
$ swift build --target MyPackageTests
$ swift test --test-product MyPackage
Building for debugging...
warning: '--product' cannot be used with the automatic product 'MyPackage'; building the default target instead
(Builds the whole project including Unsupported, and fails)
1 Like

You can run a subset of the tests with --filter, but it will only filter the test execution, not the build.

Until targets can be restricted by platform (a sorely needed feature), the standard answer to that is to make the dependency conditional, and surround each file with #if to make the target effectively empty. That way it does build successfully even though it is building essentially nothing.

1 Like