如何检测iOS应用是否在UI测试模式下运行

wnrlj8wa  于 2023-05-30  发布在  iOS
关注(0)|答案(8)|浏览(132)

我希望我的应用程序运行特殊代码(例如重置其状态)。我查看了应用程序在UI测试中运行时设置的环境变量,并且没有任何明显的参数来区分正常运行的应用程序与UI测试中的应用程序。有办法知道吗?
我不满意的两个解决方案是:
1.用一些变量设置XCUIApplication.launchEnvironment,我稍后会在应用程序中检查这些变量。这并不好,因为您必须在每个测试文件的setUp方法中设置它。我尝试从scheme设置中设置环境变量,但在运行UI Testing测试时,这不会传播到应用程序本身。
1.检查是否缺少环境变量__XPC_DYLD_LIBRARY_PATH。这看起来非常古怪,可能只是因为我们的目标构建设置的巧合而现在才起作用。

1rhkuytd

1rhkuytd1#

我自己也在研究这个问题,遇到了这个问题。我最终选择了@LironYahdav的第一个解决方案:
在UI测试中:

- (void)setUp
{
    [super setUp];

    XCUIApplication *app = [[XCUIApplication alloc] init];
    app.launchEnvironment = @{@"isUITest": @YES};
    [app launch];
}

在您的应用程序中:

NSDictionary *environment = [[NSProcessInfo processInfo] environment];
if (environment[@"isUITest"]) {
    // Running in a UI test
}

@JoeMasilotti的解决方案对于 * 单元 * 测试很有用,因为它们与被测试的应用共享相同的运行时,但与UI测试无关。

chhqkbe1

chhqkbe12#

我没有成功地设置一个启动环境,但让它与启动参数一起工作。
在测试setUp()函数中添加:

let app = XCUIApplication()
app.launchArguments = ["testMode"]
app.launch()

在你的生产代码中添加一个检查,如:

let testMode =  NSProcessInfo.processInfo().arguments.contains("testMode")
if testMode {
  // Do stuff
}

已使用Xcode 7.1.1验证。

x6yk4ghg

x6yk4ghg3#

您可以使用预处理器宏。我发现你有几个选择:

新建目标

复制App的目标,并将其作为待测目标。此目标副本中的任何前置处理器宏都可以在代码中访问。
一个缺点是你将不得不添加新的类/资源到复制目标以及有时很容易忘记。

新建配置

复制Debug构建配置,将任何预处理器宏设置为该配置,并将其用于测试(参见下面的屏幕截图)。
一个小问题:每当你想 * 录制 * 一个UI测试会话时,你需要更改 * 运行 * 以使用新的测试配置。
添加重复配置:

用于您的测试

zi8p0yeb

zi8p0yeb4#

Swift 3基于之前的答案。

class YourApplicationUITests: XCTestCase {

    override func setUp() {
        super.setUp()

        // Put setup code here. This method is called before the invocation of each test method in the class.

        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false
        // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
        let app = XCUIApplication()
        app.launchArguments = ["testMode"]
        app.launch()

        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // Use recording to get started writing UI tests.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
    }

}

extension UIApplication {
    public static var isRunningTest: Bool {
        return ProcessInfo().arguments.contains("testMode")
    }
}

然后在代码中调用UIApplication.isRunningTest。

yb3bgrhw

yb3bgrhw5#

我刚加了这个分机

@available(iOS 9, *)
 extension XCUIApplication {

 func test(){
   launchEnvironment = ["TEST":"true"]
   launch()
  }
 }

所以我可以只使用test()而不是launch()

gjmwrych

gjmwrych6#

在Swift 3中,你可以检查XCInjectBundleInto键,或者以XC开头的键。

let isInTestMode = ProcessInfo.processInfo.environment["XCInjectBundleInto"] != nil

在OS X中也是如此。

kmb7vmvb

kmb7vmvb7#

我的解决方案与上面的that of Ciryon几乎相同,除了对于我的macOS基于文档的应用,我必须在参数名称前添加连字符

let app = XCUIApplication()
app.launchArguments.append("-Testing")
app.launch()

...否则,“Testing”最终会被解释为启动应用程序时要打开的文档的名称,所以我得到了一个错误警报:

bwleehnv

bwleehnv8#

不是特定于UI测试,而是一般的测试,为ProcessInfo创建扩展

public extension ProcessInfo {
    static var isTesting: Bool {
        processInfo.environment["XCTestConfigurationFilePath"] != nil
    }
}

用途:

if ProcessInfo.isTesting {}
guard !ProcessInfo.isTesting else { return }

相关问题