Adding test target to Swift Package (--type executable)
If you have used SPM to create the command line application before Swift 5.9.0
, the project structure used to be as follows:
Package.swift
README.md
.gitignore
Sources/
Sources/SamplePackage/main.swift
Tests/
Tests/LinuxMain.swift
Tests/SamplePackageTests/
Tests/SamplePackageTests/SamplePackageTests.swift
Tests/SamplePackageTests/XCTestManifests.swift
The test target and the basic scaffolding for it were available on the package creation.
With the recent changes to simplify the templating of the package --type
, test target is only added to the package --type library
and not to --type tool
and --type executable
.
tool
is the newly added type that creates the package of type executable
with the dependency for SwiftArgumentParser already added to the package.
The new file structure looks as follows:
// --type executable
./executable
./executable/.gitignore
./executable/Package.swift
./executable/Sources
./executable/Sources/executable.swift
// --type tool
./tool
./tool/.gitignore
./tool/Package.swift
./tool/Sources
./tool/Sources/tool.swift
// --type empty
./empty
./empty/Package.swift
// --type library
./library
./library/Tests
./library/Tests/libraryTests
./library/Tests/libraryTests/libraryTests.swift
./library/.gitignore
./library/Package.swift
./library/Sources
./library/Sources/library
./library/Sources/library/library.swift
You can find more details about the change in this PR.
Now, if you want to add the test target to the package of --type tool
or --type executable
with newer tool-chain of Swift 5.9.0
, you can follow these steps:
Create the package:
$ mkdir SamplePackage $ cd SamplePackage $ swift package init --type executable
Creating executable package: SamplePackage Creating Package.swift Creating .gitignore Creating Sources/ Creating Sources/main.swift
Open
Package.swift
. It should look like this:// swift-tools-version: 5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "SamplePackage", targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. // Targets can depend on other targets in this package and products from dependencies. .executableTarget( name: "SamplePackage"), ] )
Update
Package.swift
as below:// swift-tools-version: 5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "SamplePackage", targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. // Targets can depend on other targets in this package and products from dependencies. .executableTarget( name: "SamplePackage", path: "Sources" ), .testTarget( name: "SamplePackageTests", dependencies: ["SamplePackage"], path: "Tests" ) ] )
Add
.testTarget
to the array oftargets
and add the main targetSamplePackage
to its dependencies list. Also, add the path to theTests
folder.Add a sample test file with
@testable import <main module>
to validate that the tests can resolve the main module.Example test file:
import XCTest @testable import SamplePackage class ExampleTests: XCTestCase { func testExample() { } }
The updated file structure should look as below:
SamplePackage SamplePackage/.gitignore SamplePackage/Package.swift SamplePackage/Sources SamplePackage/Sources/main.swift SamplePackage/Tests/ExampleTests.swift
Validate if tests are running successfully via Xcode
โ + U
and via the command lineswift test
Let me know if you found this helpful. Feel free to tweet me on Twitter if you have any additional tips or feedback.
Thanks.
Subscribe to my newsletter
Read articles from Javal Nanda directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Javal Nanda
Javal Nanda
๐ Hi, I'm Javal Nanda, a Mobile Application Developer based in India. I've been in the world of mobile app development since 2010, and this blog is my space to share experiences and thoughts.