3

I need to flag certain test-specific situations from production code, and since precompiled macros no longer exist in swift (and since the Other Swift Flags seems to work on a target basis, but not on a test-target specific basis) I thought I could use the test plist to access properties only available during testing.

If this strategy works, I need to access my test target plist file from the AppDelegates application:didFinishLaunchingWithOption: -method. I've a Property called TEST_TARGET in the plist, which for this example is a string.

enter image description here

A related topic is discussed here. In my AppDelegates application:didFinishLaunchingWithOption: -method I have the following lines of code:

var testSetting = NSBundle(forClass: self.dynamicType).objectForInfoDictionaryKey("TEST_TARGET") as? String
    println("Testtarget: \(testSetting)")

When run these line of code prints Testtarget: nil. However, adding the exact same lines of code in the TestClass setup-method renders the expected result of Testtarget: Optional("\"This is a test target\"")

It seems to me that NSBundle(forClass: self.dynamicType) does not return the testBundle when called from the AppDelegate, which to some extent can be logical, given that the AppDelegate class is in the mainBundle. But then, is there some way in which I can reach the testPlist from the production code? And can this be done without breaking any fundamental principles of testing and code architecture.

EDIT: Only typos

Community
  • 1
  • 1
jollyCocoa
  • 691
  • 7
  • 20

1 Answers1

3

in objC I used this:

to get the test bundle's plist:

    Class cls = NSClassFromString(@"YourOwnTestCaseClass");
    if(cls) {
        //the plist
        id dict = [[NSBundle bundleForClass:cls] infoDictionary];

        //the path to it (IF you need it)
        id testPlistPath = [[NSBundle bundleForClass:cls] pathForResource:@"Info" ofType:@"plist"];
    }

in swift I thought I could use allBundles

    let bundles = NSBundle.allBundles()
    for bundle in bundles {
        let val = bundle.objectForInfoDictionaryKey("TESTING")
        if val != nil {
            println(bundle.infoDictionary)
        }
    }

BUT NEITHER WORKS IN SWIFT


DIFFERENT SOLUTION

so I propose setting an environment var in the SCHEME for testing

enter image description here

then check it in your code like

let val = getenv("TESTING") //Val is a C String

better:

let dict = NSProcessInfo.processInfo().environment 
let testing : AnyObject? = dict["TESTING"] //get a swift object
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
  • This seems to work! Thanks. However, using getenv() returned a C pointer, which might be a bit hairy in a swift environment, but I found that using: let dict = NSProcessInfo.processInfo().environment let testing : AnyObject? = dict["TESTING"] Gave me a swift variable to work with. Related question though. What are the consequences of checking out the "Use the Run action's arguments and environment variable" checkbox? – jollyCocoa Mar 12 '15 at 08:38
  • My understanding: there are no consequences EXCEPT IF you have custom environment variables for the run scheme... those would be missing – Daij-Djan Mar 12 '15 at 09:23