Swift Cheatsheet
Packages & Testing
Use this Swift reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Swift Package Manager commands
swift package init --type executable # or --type library swift build # debug build swift build -c release # optimized build swift run # build + run the executable swift test # run all tests swift test --filter ParserTests # subset by suite/test name swift test --parallel swift package update # bump dependencies within constraints swift package resolve # pin to Package.resolved
Layout convention: sources in Sources/<Target>/, tests in Tests/<Target>Tests/.
Package.swift
The manifest must start with the tools-version comment on line 1, or it will not build:
// swift-tools-version:6.0 import PackageDescription let package = Package( name: "Practice", dependencies: [ .package(url: "https://github.com/apple/swift-collections.git", from: "1.1.0"), ], targets: [ .executableTarget( name: "Practice", dependencies: [ .product(name: "Collections", package: "swift-collections"), ] ), .testTarget(name: "PracticeTests", dependencies: ["Practice"]), ] )
The tools version also selects the language mode: 6.0 builds the package in Swift 6 mode (strict concurrency). Stay on Swift 5 semantics with the package-level swiftLanguageModes: [.v5] parameter (or a per-target .swiftLanguageMode(.v5) Swift setting) if needed.
Swift Testing (the default since Xcode 16)
import Testing @testable import Practice @Test func addsTwoNumbers() { #expect(add(2, 3) == 5) } @Test("parses negatives", arguments: ["-1", "-42"]) func parsesNegative(text: String) throws { let value = try #require(Int(text)) // unwrap or fail-and-stop #expect(value < 0) } @Suite("Parser") struct ParserTests { @Test func emptyInputThrows() { #expect(throws: ParseError.empty) { try parse("") } } @Test(.disabled("tracked in #42")) func flakyPath() { } }
#expect records a failure and keeps going, #require aborts the test. Failure output shows the values of each sub-expression, so one macro replaces the whole XCTAssert* family. Parameterized tests run once per argument. Async tests just add async and use await.
XCTest (legacy, still ubiquitous)
import XCTest @testable import Practice final class SolverTests: XCTestCase { override func setUp() { super.setUp() // runs before each test method } func testAdds() { XCTAssertEqual(add(2, 3), 5) } func testThrowsOnEmpty() { XCTAssertThrowsError(try parse("")) { error in XCTAssertEqual(error as? ParseError, .empty) } } func testFetch() async throws { let value = try await fetchScore(id: 1) XCTAssertGreaterThan(value, 0) } }
XCTest and Swift Testing suites coexist in one swift test run, so codebases migrate incrementally. UI and performance tests (XCUIApplication, measure {}) remain XCTest-only.
Single-file practice
For online compilers and DSA judges, one main.swift with top-level code is the simplest shape:
swift main.swift # run directly swiftc -O main.swift -o sol && ./sol # compile optimized, then run swift --version
Move to a package when you need multiple files, dependencies, or a test suite.