Creating a framework that uses XCTest
You have to add additional Framework Search Path in the Build Settings:
$(PLATFORM_DIR)/Developer/Library/Frameworks
Cannot load underlying module for XCTest
The main project does not link with the XCUnit framework. You should create a separate testing target for your project, if one does not already exist, and add your test source files to that target.
- Select your project in the Project Navigator. This will open the project's settings in the editor.
- Click the "+" button at the bottom of the column listing your Targets.
If you are working on an iOS project template, select
iOS > Test > iOS Unit Testing Bundle
.If you are working on an OS X project template, select
OS X > Test > OS X Unit Testing Bundle
.
Not able to use XCTUnwrap in Test Framework
The XCTUnwrap
API is only available in primary test bundle targets and not in other libraries or frameworks. There are two ways to fix this issue:
- Move your
Optional
extension to the main bundle which obviously not something you want to do :) - Modify the following build settings in your test framework target:
SYSTEM_FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PLATFORM_DIR)/Developer/usr/lib",
);
SWIFT_INCLUDE_PATHS = "$(inherited) $(PLATFORM_DIR)/Developer/usr/lib"
Why in iOS Framework, xctest is always red colour?
No, Scheme(not schema) is different from Target. Check out this thread for better understanding Xcode: What is a target and scheme in plain language?
To solve your issue, click on the WSBandKit framework icon on top left section(adjacent to iPad2 simulator icon); and select editScheme
option from drop down. You will be presented with a new screen with some option. Go to Build option and tick the option of Run
for your test target. Close the screen and Build the framework for Device.
Check the image for reference. Initially the Run
option will be unchecked for test target that you have to check.
How to reliably install and setup Quick test framework on Xcode 8?
Git submodule way is the most lean and simple way to achieve that.
Follow the these steps to start from zero:
1.a. Create Xcode project with Include Unit Tests
checked.
1.b. Alternatively, you could create unit test target
on existing project.
- Open test Navigator.
- Click the + button in the lower-left corner, then select New Unit Test Target… from the menu:
2. Close the Xcode project in (1)
3. Create new Xcode workspace. File -> New -> Workspace.
4. Open Terminal / Bash Shell / Cmd.exe
5. Create a new sub directory for GitHubProjectClones.
- for example: $HOME/Developer/GitHubProjectClones
6. cd to sub directory in (5):
- mkdir Vendor
- git init
7. Follow step one
in Git Submodule section
- git submodule add git@github.com:Quick/Quick.git Vendor/Quick
- git submodule add git@github.com:Quick/Nimble.git Vendor/Nimble
- git submodule update --init --recursive
8. Follow step two
in Git Submodule section
.
- Back to Xcode with Workspace open:
- Make sure Project Navigator is selected
- File -> Add files to:
- select the Quick folder created in step 7.
- File -> Add files to:
- select the Nimble folder created in step 7.
- File -> Add files to:
- select your Xcode project in step 1.
- File -> Add files to:
- Make sure Project Navigator is selected
9. Follow step three
in Git Submodule section
to link Quick.framework
and Nimble.framework
during your test target's Link Binary with Library
build phase.
10. You should be able to follow along the examples in Quick Documentation
Unable to load custom font during XCTest in framework I'm creating
I was able to solve this issue by loading the font file as data and then creating a font using CGFontCreateWithDataProvider. Here is my loadCustomFont method:
func loadCustomFont(name: String, fontExtension: String) -> Bool {
let fileManager = NSFileManager.defaultManager()
let bundleURL = NSBundle(forClass: USDFont.self).bundleURL
do {
let contents = try fileManager.contentsOfDirectoryAtURL(bundleURL, includingPropertiesForKeys: [], options: .SkipsHiddenFiles)
for url in contents {
if url.pathExtension == fontExtension {
let fontData = NSData(contentsOfURL: url)
let provider = CGDataProviderCreateWithCFData(fontData)
if let font = CGFontCreateWithDataProvider(provider) {
CTFontManagerRegisterGraphicsFont(font, nil)
}
}
}
} catch {
print("error: \(error)")
}
return true
}
Once I loaded fonts this way (instead of the usual Info.plist way), I was able to load the font during the XCTest.
iOS Framework Tests fail in Xcode Workspace
After looking at the issue again, I could find the reason for the strange behaviour.
Short Answer:
There is a private OAuth Apple Framework located at /System/Library/PrivateFrameworks/OAuth.framework/OAuth
which causes a name clash with my own OAuth framework because xctest
seems to link this framework.
Long Answer:xctest
or XCTest.framework
seem to load an OAuth.framework from the Private Frameworks folder.
If one uses a workspace within Xcode, the test environment uses the following environment variable for dyld:
"DYLD_FRAMEWORK_PATH“ = "/Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks“;
The variable has the following effects:
DYLD_FRAMEWORK_PATH
This is a colon separated list of directories that contain frameworks. The dynamic linker
searches these directories before it searches for the framework by its install name. It
allows you to test new versions of existing frameworks. (A framework is a library install name
that ends in the form XXX.framework/Versions/YYY/XXX or XXX.framework/XXX, where XXX and YYY
are any name.)
For each framework that a program uses, the dynamic linker looks for the framework in each
directory in DYLD_FRAMEWORK_PATH in turn. If it looks in all the directories and can't find
the framework, it searches the directories in DYLD_LIBRARY_PATH in turn. If it still can't
find the framework, it then searches DYLD_FALLBACK_FRAMEWORK_PATH and DYLD_FALL-BACK_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH
BACK_LIBRARY_PATH in turn.
DYLD_FRAMEWORK_PATH
defines the search directories for Frameworks and overrides the default search paths and the install names, which embedded into the depending binary. Even if a binary specifies a framework install path like
/System/Library/Frameworks/OAuth
the environment variable leads to the behaviour that the directory/Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator
is searched for an OAuth.framework/OAuth
binary regardless of the actual install name.
This behaviour is intended since it allows for overriding Frameworks in an existing binary with newer versions without the need to recompile the binary.
However, it can also entail misleading linking of binaries if two Frameworks have to same names. Then, one of the Frameworks with the same name could be loaded even if the other one is specified by path. If the directory of the first one is contained in the DYLD_FRAMEWORK_PATH
either prior to the other one’s directory or at all, then the first one is picked because of its name and regardless of the specified install name path.
Concrete Example:
xctest binary load command:/System/Library/PrivateFrameworks/OAuth.framework/OAuth (compatibility version 300.0.0, current version 1280.24.0)
OAuth is present at the following paths:/System/Library/PrivateFrameworks/OAuth.framework/OAuth
/Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator/OAuth.framework/OAuth
xctest is started with the following environment variable:"DYLD_FRAMEWORK_PATH“ = "/Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks“;
Then the OAuth Framework at/Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator/OAuth.framework/OAuth
is used even if the install name is/System/Library/PrivateFrameworks/OAuth.framework/OAuth
Related Topics
Why am I Getting Com.Facebook.Sdk.Login Error 308
iOS with Parse. Pfuser.Currentuser() Not Getting Cached. Returns Nil After App Restart
How to Change Searchbar Border Color
Swift Core Data Sync with Web Server
How to Get Date from String in Swift 3
Fft Calculating Incorrectly - Swift
How to Send Different Users to Separate View Controllers Using Firebase and Xcode
Swift: Protocol VS. Struct VS. Class
iOS Swift - Custom Camera Overlay
Dismiss Keyboard with Swipe Gesture
How to Bridge Nsnumber to Float in JSON Parsing
Where to Find a Clear Explanation About Swift Alert (Uialertcontroller)
How to Pass in a Void Block to Objc_Setassociatedobject in Swift
Cannot Set Color of Button's Label Inside Menu in Swiftui