使用 XCTestCase Objective-C 进行多次测试性能

Posted

技术标签:

【中文标题】使用 XCTestCase Objective-C 进行多次测试性能【英文标题】:multiple testPerformance with XCTestCase objective-C 【发布时间】:2014-08-05 18:04:50 【问题描述】:

我在测试类中有 2 种性能测试方法。如果我单独运行它们,它们会通过。如果我运行孔类方法,它们会失败并显示消息:

**** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“API 违规 - 多次调用 -[XCTestExpectation 完成]。”*

有没有办法将一对性能测试包含在一个类中?

这里是示例代码:

- (void)testPerformanceAuthenticateWithLogin 
    XCTestExpectation *authenticateExpectation = [self expectationWithDescription:@"Authenticate With Login"];
    __block int userID = 0;
    [self measureBlock:^
        [AuthenticationService authenticateWithLogin:email password:password success:^(AuthenticationResponse *result) 
            XCTAssert(result.isAuthenticated);
            userID = result.userID;
            [authenticateExpectation fulfill];
         failure:^(NSError *error) 
            XCTAssertNil(error);
        ];
    ];
    [self waitForExpectationsWithTimeout:3 handler:^(NSError *error) 
        XCTAssertNil(error);
        [AuthenticationService logoutWithServicePersonID:userID success:nil failure:nil];
    ];


- (void)testPerformanceGetServicePersonByID 
    XCTestExpectation *getServicePersonExpectation = [self expectationWithDescription:@"get Service Person By ID"];
    __block int userID = 0;
    [AuthenticationService authenticateWithLogin:email password:password success:^(AuthenticationResponse *result) 
        userID = result.userID;
        [self loginSuccess:result];
        [self measureBlock:^
            [ServicePersonService getServicePersonByIDWithServicePersonID:userID success:^(ServicePersonDTO *result) 
                XCTAssertNotNil(result);
                [getServicePersonExpectation fulfill];
             failure:^(NSError *error) 
                XCTAssertNil(error);
            ];
        ];
     failure:^(NSError *error) 
        XCTAssertNil(error);
    ];

    [self waitForExpectationsWithTimeout:3 handler:^(NSError *error) 
        XCTAssertNil(error);
        [AuthenticationService logoutWithServicePersonID:userID success:nil failure:nil];
    ];

【问题讨论】:

我在同一个类中有多个测试,每个测试都有一个 XCTestExpectation 并且工作正常。虽然我没有使用 measureBlock 。如果每次通过时只运行一个 measureBlock 是否有效? 【参考方案1】:

measureBlock 实际上多次运行块内的代码以确定平均值。

如果我理解正确,您想测量身份验证需要多长时间。如果是这样的话:

您可以将期望放在测量块中,这样每次测量迭代完成时,测试迭代都会等待期望得到满足,然后再次执行块 您可以稍微提高预期超时时间以防万一。

我做过这样的事情(对我有用):

- (void)testPerformanceAuthenticateWithLogin 
    [self measureBlock:^
        __block int userID = 0;
        XCTestExpectation *authenticateExpectation = [self expectationWithDescription:@"Authenticate With Login"];

        [AuthenticationService authenticateWithLogin:email password:password success:^(AuthenticationResponse *result) 
            XCTAssert(result.isAuthenticated);
            userID = result.userID;
            [authenticateExpectation fulfill];
         failure:^(NSError *error) 
            XCTAssertNil(error);
        ];

        [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) 
            XCTAssertNil(error);
            [AuthenticationService logoutWithServicePersonID:userID success:nil failure:nil];
        ];
    ];

【讨论】:

委托模式是否可行?在我的情况下,当我调用身份验证服务时,我必须提供选择器(方法名称),并且在响应回调函数时将被调用,因此我的 [期望实现] 在另一个函数中,而不是 -(void)testLogin; 我不明白为什么不这样做,但在您的情况下,您必须将 XCTestExpectation *authenticateExpectation 保存在单独的属性中,并可能在某个时候将其设置为 nil。

以上是关于使用 XCTestCase Objective-C 进行多次测试性能的主要内容,如果未能解决你的问题,请参考以下文章

在 Objective-C 中循环 BOOL

如何在静态 objc 库中使用 XCTestcase

如何使用 XCTestCase 测试异步代码

XCTestCase 异步

XCTestCase:使用 IndexPath 点击 collectionView 中的单元格

如何在 XCTestCase 中测试 NSPersistentDocument?