Quick: `swift test` doesn't actually run tests on macOS

  • I have read CONTRIBUTING and have done my best to follow them.

What did you do?

  1. Created a simple Spec:
import Quick
import Nimble

class ThingsSpec: QuickSpec {
  override func spec() {
    describe("test") {
      it("does the thing") {
        expect(true).to(beTrue())
      }
    }
  }
}
  1. Ran swift test

What did you expect to happen?

I expected it to properly run the test spec, and output the results.

What actually happened instead?

Instead, I got the following output:

Test Suite 'All tests' started at 2017-01-14 00:03:05.037
Test Suite '[REDACTED]PackageTests.xctest' started at 2017-01-14 00:03:05.038
Test Suite '[REDACTED]PackageTests.xctest' passed at 2017-01-14 00:03:05.038.
         Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.000) seconds
Test Suite 'All tests' passed at 2017-01-14 00:03:05.038.
         Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.001) seconds

Environment

List the software versions you’re using:

  • Quick: 1.0.0
  • Nimble: 5.1.1
  • Xcode Version: Irrelevant
  • Swift Version: Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)
  • Swift Package Manager 3.0.2 (swiftpm-11750)

Project that demonstrates the issue

I can’t link directly to the project in question, as it is closed source, but I had the same problem when attempting to verify the issue with ReactiveCocoa/ReactiveSwift .

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 26 (11 by maintainers)

Most upvoted comments

I try to explain…

  • SwiftPM does not support a mixed-language target of Swift and Objective-C. Quick on macOS consists of the both languages. The Swift part depends on the Objective-C part and vice versa.
    • Because of the language limitation that Objective-C classes cannot extend Swift classes, QuickSpec must be defined in Objective-C.
    • We need to use NSInvocation related APIs of XCTestCase in XCTest on macOS, but NSInvocation cannot be used from Swift. This is also the reason why we use Objective-C.
    • Even if we split our codebase into Swift one and Objective-C one, SwiftPM does not allow an Objective-C target to use a Swift target (but the opposite is allowed).
  • In SwiftPM on Linux, we are using pure Swift implementation (we don’t care Objective-C users in this case) which is based on LinuxMain.swift entry point , testCase and XCTMain APIs. Thanks to those, we can define QuickSpec in Swift and can run examples without any use of NSInvocations.
  • Even if we choose the same pure Swift implementation in SwiftPM on macOS, swift test on macOS runs using ObjC XCTest so we must provide examples of a spec through NSInvocationss and that can’t be achieved. There is no LinuxMain.swift, testCase and XCTMain APIs in ObjC XCTest.

I’ll take another look at #600 and this issue, and in the next 2-3 days try to write up exactly what would need to be done, in either Quick or in SwiftPM, in order to allow users to successfully run swift test.

This can’t be done cleanly yet, but could you have an Obj-C implementation target which:

  1. Was excluded on Linux (it will have to have another non-empty C file so that you can still depend on it)
  2. Is depended on by the actual Swift target.
  3. Just provides the hooks needed to create the dynamic NSInvocations ?

A question on this came up in SwiftPM Slack discussion today… is this something blocked on Quick or blocked on SwiftPM? It isn’t clear to me from the discussion here…