XCTest from repl


(Lou Zell) #1

Greetings,

I am close to getting XCTests running in the swift repl, but for some
reason my tests are never invoked. Does anyone have a suggestion or see
something wrong with the test setup?

$ xcrun swift -F
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks

import Foundation // If you're copy pasting, copy paste these
individually!// If you get a null pointer back, use perror(dlerror())
to get a description of the
errordlopen("/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework/Versions/A/XCTest",
RTLD_NOW)dlopen("/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftXCTest.dylib",
RTLD_NOW)import XCTest
class MyTest : XCTestCase {
    override func setUp() {
        super.setUp()
        print("Setting up")
    } override func tearDown() {
        super.tearDown() print("Tearing down")
    }
    func testIt() {
        print("I'm never here")
        XCTAssertTrue(false, "I never see this!")
    } }

let suite = XCTestSuite(name: "foo")suite.addTest(MyTest())suite.run()

I see the "setting up" and "tearing down" output, but I never see the print
inside -testIt. Any ideas?

Thanks,
Lou


(Brian Gesiak) #2

Lou,

Wow, this is awesome!! Excellent work.

I have a few ideas as to why you’re not actually seeing any tests run:

   1. swift-corelibs-xctest expects users to run tests via the XCTMain()
   function
   <https://github.com/apple/swift-corelibs-xctest/blob/96144ded862f402a742345b38f8324cf108f0398/Sources/XCTest/Public/XCTestMain.swift#L52>.
   I’m not sure it’s appropriate for your use case, since the function calls
   exit() directly (and thus has a return type of Never). If it does fits
   your use case, I’d suggest using it, since all of swift-corelibs-xctest’s
   regression tests assume this function is called.
   2. swift-corelibs-xctest lacks the runtime reflection used by Apple
   XCTest, and so requires users to list their test methods
   <https://github.com/apple/swift-corelibs-xctest/blob/1f00ab2c677d9c226dea8fa3f541999d6f4405b6/Sources/XCTest/Private/XCTestCaseSuite.swift#L31>.
   I think you may see the testIt() output by adding the following:

class MyTest : XCTestCase { + static var allTests = {+
return [+ ("testIt", testIt),+ ]+ }()
    override func setUp() {

Let me know if that works!

- Brian Gesiak

···

On Mon, Aug 8, 2016 at 3:25 PM, Lou Zell via swift-users < swift-users@swift.org> wrote:

Greetings,

I am close to getting XCTests running in the swift repl, but for some
reason my tests are never invoked. Does anyone have a suggestion or see
something wrong with the test setup?

$ xcrun swift -F /Applications/Xcode-beta.app/
Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks

import Foundation // If you're copy pasting, copy paste these individually!// If you get a null pointer back, use perror(dlerror()) to get a description of the errordlopen("/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework/Versions/A/XCTest", RTLD_NOW)dlopen("/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftXCTest.dylib", RTLD_NOW)import XCTest
class MyTest : XCTestCase {
    override func setUp() {
        super.setUp()
        print("Setting up")
    } override func tearDown() {
        super.tearDown() print("Tearing down")
    }
    func testIt() {
        print("I'm never here")
        XCTAssertTrue(false, "I never see this!")
    } }

let suite = XCTestSuite(name: "foo")suite.addTest(MyTest())suite.run()

I see the "setting up" and "tearing down" output, but I never see the
print inside -testIt. Any ideas?

Thanks,
Lou

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Lou Zell) #3

Thanks Brian!

You pointed me in the right direction. I've got a working version up here:
https://gist.github.com/lzell/3a4f43d00657a347363343c035e5db4c

Non-pretty version:

// Start repl with:
// $ xcrun swift -F
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks

// Or run as script:
// $ xcrun swift -F
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks
%

import Foundation

if
dlopen("/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework/Versions/A/XCTest",
RTLD_NOW) == nil {
  perror(dlerror())
}
if
dlopen("/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftXCTest.dylib",
RTLD_NOW) == nil {
  perror(dlerror())
}

import XCTest

class ATest : XCTestCase {
    func testIt() {
        XCTAssertTrue(false, "Now I see this!")
    }
    func testThat() {
        XCTAssertNil(nil, "Passes!")
    }
}

class BTest : XCTestCase {
  func testIt() {
    XCTAssertFalse(false, "whatever")
  }
  func testThat() {
    XCTAssertEqual(1, 0, "I fail too")
  }
}

// MARK: -
func selectors<T: XCTestCase>(forType type: T.Type) -> [Selector] {
  var selectors = [Selector]()
  var count : UInt32 = 0
  let methods = class_copyMethodList(type, &count)!
  for i in 0..<count {
    let method = methods.advanced(by: Int(i)).pointee!
    selectors.append(method_getName(method)!)
  }
  return selectors
}

func runTests(_ types: XCTestCase.Type...) {
  let suite = XCTestSuite(name: "Required")
  for t in types {
    let tests = selectors(forType: t).filter() {
String($0).hasPrefix("test") }
    tests.map(t.init)
         .forEach(suite.addTest)
  }
  suite.run()
}

runTests(ATest.self, BTest.self)

Lou

···

On Mon, Aug 8, 2016 at 10:05 PM, Brian Gesiak <modocache@gmail.com> wrote:

Lou,

Wow, this is awesome!! Excellent work.

I have a few ideas as to why you’re not actually seeing any tests run:

   1. swift-corelibs-xctest expects users to run tests via the XCTMain()
   function
   <https://github.com/apple/swift-corelibs-xctest/blob/96144ded862f402a742345b38f8324cf108f0398/Sources/XCTest/Public/XCTestMain.swift#L52>.
   I’m not sure it’s appropriate for your use case, since the function calls
   exit() directly (and thus has a return type of Never). If it does fits
   your use case, I’d suggest using it, since all of swift-corelibs-xctest’s
   regression tests assume this function is called.
   2. swift-corelibs-xctest lacks the runtime reflection used by Apple
   XCTest, and so requires users to list their test methods
   <https://github.com/apple/swift-corelibs-xctest/blob/1f00ab2c677d9c226dea8fa3f541999d6f4405b6/Sources/XCTest/Private/XCTestCaseSuite.swift#L31>.
   I think you may see the testIt() output by adding the following:

class MyTest : XCTestCase { + static var allTests = {+ return [+ ("testIt", testIt),+ ]+ }()
    override func setUp() {

Let me know if that works!

- Brian Gesiak

On Mon, Aug 8, 2016 at 3:25 PM, Lou Zell via swift-users < > swift-users@swift.org> wrote:

Greetings,

I am close to getting XCTests running in the swift repl, but for some
reason my tests are never invoked. Does anyone have a suggestion or see
something wrong with the test setup?

$ xcrun swift -F /Applications/Xcode-beta.app/C
ontents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks

import Foundation // If you're copy pasting, copy paste these individually!// If you get a null pointer back, use perror(dlerror()) to get a description of the errordlopen("/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework/Versions/A/XCTest", RTLD_NOW)dlopen("/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftXCTest.dylib", RTLD_NOW)import XCTest
class MyTest : XCTestCase {
    override func setUp() {
        super.setUp()
        print("Setting up")
    } override func tearDown() {
        super.tearDown() print("Tearing down")
    }
    func testIt() {
        print("I'm never here")
        XCTAssertTrue(false, "I never see this!")
    } }

let suite = XCTestSuite(name: "foo")suite.addTest(MyTest())suite.run()

I see the "setting up" and "tearing down" output, but I never see the
print inside -testIt. Any ideas?

Thanks,
Lou

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users