简体   繁体   English

检查UIAlertController是否在XCTest案例中呈现

[英]Check if UIAlertController is Presented in an XCTest Case

I'm writing unit tests for an application and want to check if a UIAlertController is presented in a specific scenario. 我正在为应用程序编写单元测试,并想检查是否在特定场景中呈现了UIAlertController

-(void)testBadLogin {
    // enter username and password in UITextFields
    self.viewController.usernameField.text = @"test@test.com";
    self.viewController.passwordField.text = @"incorrect_pass";
    [loginButton sendActionsForControlEvents: UIControlEventTouchUpInside];

    // this isn't right
    XCTAssertNotNil([self.viewController alertController], @"alertController should appear"); 
}

How do I check if a UIAlertController has been presented on top of the current view? 如何检查UIAlertController是否已显示在当前视图之上?

"XCTest is not meant to be used to test UI components." “XCTest并不意味着用于测试UI组件。” is not truly accurate. 不是真的准确。 I am using XCTest for almost every UI testing and it works just fine. 我正在使用XCTest进行几乎所有的UI测试,它运行得很好。 The correct answer shall be "Mocking". 正确答案应为“嘲弄”。

I would use OCMock for mocking the tested view controller and "verify" that the method presentViewController... is called with the alert controller. 我会使用OCMock来模拟测试的视图控制器,并“验证”使用警报控制器调用方法presentViewController ... This is a neat solution and works just fine. 这是一个简洁的解决方案,工作得很好。 (You can even ignore that the alert controller is passed to this method and just test that the view controller has been passed the method presentViewController...) (你甚至可以忽略警报控制器传递给这个方法,只是测试视图控制器已经传递了方法presentViewController ...)

It can also be done in this way: 它也可以这样做:

Let's say we have a button which when tapped shows view controller: 假设我们有一个按钮,当点击时显示视图控制器:

- (void) didTapButton
{
    UIAlertController* c = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message"
                                                        preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController:c animated:ANIMATED completion:nil];
}

Notice that ANIMATED parameter is not 'YES' or 'NO'. 请注意,ANIMATED参数不是“YES”或“NO”。 It is define in PrefixHeader as: 它在PrefixHeader中定义为:

#define ANIMATED (getenv("runningTests") == NULL)

and runningTests is environment variable defined in Test target. 而runningTests是测试目标中定义的环境变量。 We don't want animation when executing unit/integration tests. 我们在执行单元/集成测试时不需要动画。

The test method looks like: 测试方法如下:

- (void) testButtonWillShowAlertView
{
    UIApplication.sharedApplication.delegate.window.rootViewController = controller;
    [controller.button sendActionsForControlEvents:UIControlEventTouchUpInside];
    XCTAssertEqualObjects(controller.presentedViewController.class, UIAlertController.class);
}

Important line is 重要的是

UIApplication.sharedApplication.delegate.window.rootViewController = controller;

Apparentely, rootViewController on UIWindow has to be set. 显然,必须设置UIWindow上的rootViewController。

I have written a wrapper around UIAlertController for easier unit testing. 我在UIAlertController周围编写了一个包装器,以便于单元测试。

You can check if it is visible 您可以检查它是否可见

XCTAssert(testableAlert.visible)

And you can also execute its actions 而且你也可以执行它的动作

testableAlert.simulateAction("OK")

https://github.com/exchangegroup/TestableAlert https://github.com/exchangegroup/TestableAlert

you can simply check the existence for UIAlertController By below code(objective c). 你可以通过下面的代码(目标c)简单地检查UIAlertController的存在。

XCTAssertFalse(app.alerts.element.staticTexts[@"your alert message"].exists);

it will fail the test if alert is not presented, otherwise you can use 如果没有出现警报,它将无法通过测试,否则您可以使用

app.alerts.element.staticTexts[@"your alert message"].exists 

with if or XCTAssertTrue . 使用if或XCTAssertTrue。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM