On Thu, Jan 26, 2017 at 6:37 AM, thislooksfun via swift-evolution < swift-evolution@swift.org> wrote:
-thislooksfun (tlf)
On Jan 25, 2017, at 2:07 AM, Ankit Aggarwal via swift-evolution < > swift-evolution@swift.org> wrote:
On 25-Jan-2017, at 4:02 AM, Robert Widmann via swift-evolution < > swift-evolution@swift.org> wrote:
Hello Swift Community,
Harlan Haskins and I have been working on libraries
<https://github.com/trill-lang> to make interacting with LLVM and Clang’s
APIs more elegant with native Swift interfaces. While writing up the
packages we realized the package manager wouldn’t allow us to specify
testing targets and test-only dependencies. To rectify that, I have
attached a draft proposal for adding test-only targets and dependency
fields to the Swift Package manager. This proposal can also be read in
gist form
<https://gist.github.com/CodaFi/6bd83e5315c7d30aeaf4154ed3b03a38>\.
Cheers,
~Robert Widmann
Thanks for driving this! It is a very desirable feature which needs
proposal work. Comments inline.
Test-Only Package Dependencies and Targets
- Proposal: SE-NNNN <https://gist.github.com/CodaFi/NNNN-filename.md>
- Authors: Harlan Haskins <https://github.com/harlanhaskins>, Robert
Widmann <https://github.com/codafi>
- Review Manager: TBD
- Status: Awaiting review
<Proposal.md · GitHub;
Introduction
This proposal reinstates Swift package manager’s ability to fetch
dependencies and build targets scoped exclusively to the testing module(s)
of a given package.
Swift-evolution thread: Discussion thread topic for that proposal
<https://lists.swift.org/pipermail/swift-evolution/>
<Proposal.md · GitHub;
Motivation
Soon after SE-0019
<https://github.com/apple/swift-evolution/blob/master/proposals/0019-package-manager-testing.md#test-only-dependencies> identified
the need for richer test-only dependencies and targets, a decision was made
to remove the package manager’s fledgling ability to treat certain
dependencies as test-only. This has led to a myriad of
clever-but-needlessly-complex workarounds ([1]
<https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/.travis.yml#L85>
, [2] <https://github.com/ReactiveX/RxSwift/blob/master/Package.swift#L3>
, [3] <https://github.com/Quick/Quick/blob/master/.Package.test.swift>\)
on the part of 3rd parties to recover the feature themselves. In addition,
the Swift community has come up with a number of their own frameworks to
augment functionality in XCTest but depending on these external testing
frameworks is brittle and difficult to get right.
<Proposal.md · GitHub
solution
We propose the re-introduction of the testDependencies parameter in
Package Manifests to support external test-only dependencies. To support
local test-only targets we also propose the introduction of the
testTargets parameter and an extension of the existing swift test command
to support individual invocation of these targets.
<Proposal.md · GitHub
design
The behavior of the new testDependencies parameter mirrors that of the
existing dependencies parameter with one important difference: fetched
dependencies are only built to support package-defined test targets as part
of an invocation of swift test.
import PackageDescription
let package = Package(
name: "Foo",
targets: [
Target(name: "Foo")
],
dependencies: [
.Package(url: "https://github.com/org/ana.git", versions: Version(1,0,0)...Version(1,9,9)),
],
testDependencies: [
.Package(url: "https://github.com/org/anism.git", versions: Version(1,0,0)...Version(1,9,9)),
]
)
I think this feature should be called local dependencies (or maybe dev
dependencies) because it can be used for tests as well as regular targets.
As an example say you have a networking library package and you want to
create an example CLI target which uses a JSON mapper package. You wouldn't
want to vend the CLI tool when you act as a dependency to other packages,
or include the JSON mapper in your dependencies. Test dependency doesn't
sound right in that context.
After the product proposal
<https://github.com/apple/swift-evolution/blob/master/proposals/0146-package-manager-product-definitions.md> is
implemented, you will be able to control what you vend to your clients, and
we thought about adding ability to define dependencies in-line with target
dependencies but left it out of the proposal to keep it simpler. Maybe this
proposal can add that instead of a separate `testDependencies` property.
Consider this manifest:
let package = Package(
name: "FooNetworking",
targets: [
Target(
name: "FooNetworking"),
Target(
name: "FooNetworkingExample",
dependencies: [
"FooNetworking",
.package(url: "/path/to/BarJSON.git", version: "1.0.0", product: "BarJSON"), // Note: This doesn't actually exists right now.
]),
Target(
name: "FooNetworkingTests",
dependencies: [
"FooNetworking",
.package(url: "/path/to/Quick.git", version: "1.0.0", product: "Quick"), // Note: This doesn't actually exists right now.
]),
],
products: [
.Library(name: "FooNetworking", targets: ["FooNetworking"]),
])
This manifest defines three targets and one product.
*FooNetworking*: The base target and the actual library.
*FooNetworkingExample*: The example cli tool. It depends on
*FooNetworking* target and *BarJSON* product from an external package.
*FooNetworkingTests*: The test target depends on an external package
*Quick*.
Both *BarJSON* and *Quick* are local dependencies to this package. If
*FooNetworkingExample* was also vended as a product, *BarJSON* would
automatically become a regular external dependency.
Similarly, the behavior of the testTargets field mirrors that of the
existing targets field but defines a set of targets that are only built
during an invocation of swift test. Importantly, a target defined in
testTargets may reference a target defined in targets but not vice-versa.
Should that behavior be needed, the test target should be promoted to a
“full” target.
import PackageDescription
let package = Package(
name: "SwiftPM",
targets: [
Target(
name: "PackageDescription",
dependencies: ),
// MARK: Support libraries
Target(
/** Cross-platform access to bare `libc` functionality. */
name: "libc",
dependencies: ),
Target(
/** “Swifty” POSIX functions from libc */
name: "POSIX",
dependencies: ["libc"]),
Target(
/** Basic support library */
name: "Basic",
dependencies: ["libc", "POSIX"]),
/* Omitted for Brevity */
],
testTargets: [
Target(
name: "BasicPerformanceTests",
dependencies: ["Basic"]),
/* Omitted for Brevity */
]
)
Finally, with well-defined test targets in hand, we propose swift test be
amended to support individual test execution.
We propose the following syntax to execute all tests of all known test
targets.
$ swift test
To run a set of specific test cases, reference the module-defining test
target and the specific name of a subclass of XCTestCase:
$ swift test TestModule.TestCase
To run an individual test case, reference the module-defining test target,
the name of the test case subclass, and the name of the test:
$ swift test TestModule.TestCase.exampleTest
We already have all these features. A target is a test target if it has a
suffix *Tests *and is placed under *Tests/ *directory — we might loosen
these restrictions with custom target conventions feature. This proposal
<https://github.com/apple/swift-evolution/blob/master/proposals/0129-package-manager-test-naming-conventions.md> could
clarify further.
Here is a summary of what `swift test` currently supports:
* Test targets are only built (and run) when you run `swift test`.
* `swift test --skip-build` skips building of test targets and runs
whatever was last built.
* `swift test -s <test-module>.<test-case>` will run a test case class.
* `swift test -s <test-module>.<test-case>/<test>` will run an individual
test.
* `swift test --list-tests` will list all tests in above format.
* `swift test --parallel` will run tests in parallel.
You can view these options and their help text using `swift test --help`.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution