【问题标题】:XCTAssertThrows stops at breakpointXCTAssertThrows 在断点处停止
【发布时间】:2014-02-25 16:39:37
【问题描述】:

我正在编写一个测试方法,我希望 SUT 在某些条件下抛出异常。代码如下所示:

- (void) testCantStartTwice
{
    XCTAssertThrows([self.sut start], @"");
}

现在,一切都很好,测试通过了。但是,我让 Xcode 为所有 ObjC 异常设置了一个异常断点,这在调试器中测试应用程序时非常有用。就像你现在一样,现在当我使用 ⌘U 执行我的测试套件时,它会在该测试处停止并且看起来好像失败了,即使它说“测试成功”。

有什么方法可以使断点在该测试中停止

谢谢,一切顺利

【问题讨论】:

    标签: ios xctest


    【解决方案1】:

    不幸的是,异常断点似乎不可能忽略XCTAssertThrows(或现在的XCTAssertThrowsError)中包装的任何内容。

    解决方法 1:处理断点或围绕它们的脚本

    当您执行这些测试时,您可以执行以下任一操作:

    • 禁用异常断点。
    • 每次遇到您的一个断点时运行。

    两者都不理想,因为您将做一些手工工作。

    how to disable breakpoints for Swift XCTAssertThrowsError assertions here 的建议。我没有测试过这些。

    解决方法 2:改为返回 Result<T, Error>

    我原来的方法是这样的:

    struct Truck {
      static func makeTruck(numberOfWheels: Int) throws -> Self {
        if numberOfWheels < 4 {
          throw TruckError.tooFewWheels
        }
    
        // ...
    
        return .init()
      }
    }
    
    // Code example:
    let truck: Truck? = try? Truck.makeTruck(numberOfWheels: 1)
    
    // Test example:
    XCTAssertThrowsError(try Truck.makeTruck(numberOfWheels: 1))
    

    为了解决这个断点问题,我通过返回 Result 而不是抛出 Error,创建了一个更可测试的重复内部函数(因为它不会导致断点问题)。

    struct Truck {
      static func _makeTruck(numberOfWheels: Int) -> Result<Truck, Error> {
        if numberOfWheels < 4 {
          return .failure(TruckError.tooFewWheels)
        }
    
        // ...
    
        return .success(.init())
      }
    
      static func makeTruck(numberOfWheels: Int) throws -> Self {
        switch _makeTruck(numberOfWheels: numberOfWheels) {
        case .failure(let error):
          throw error
        case .success(let value):
          return value
        }
      }
    }
    
    // Code example:
    let truck: Truck? = try? Truck.makeTruck(numberOfWheels: 1)
    
    // Test example:
    XCTAssertEquals(Truck._makeTruck(numberOfWheels: 1), .error(TruckError.tooFewWheels))
    

    解决方法 3:改为返回 T?

    最后,如果您有一个更简单的用例,并且您的函数的失败非常明显(例如,它只能返回一种类型的错误),请考虑只返回一个可选项而不是需要复杂的 Result类型:

    struct Truck {
      static func makeTruck(numberOfWheels: Int) -> Truck? {
        if numberOfWheels < 4 {
          return nil
        }
    
        // ...
    
        return .init()
      }
    }
    
    // Code example:
    let truck: Truck? = Truck.makeTruck(numberOfWheels: 1)
    
    // Test example:
    XCTAssertNil(Truck.makeTruck(numberOfWheels: 1))
    

    【讨论】:

      【解决方案2】:

      也许您可以在测试时使用测试失败断点而不是异常断点。 wwdc 2013 单元测试视频概述了一个非常好的检查测试失败的工作流程。它本质上说:

      1. 设置一个测试失败断点,这将允许您检查导致失败的条件。
      2. 如果需要,请在测试的早期设置手动断点并重新运行,这样您就可以像往常一样单步执行导致失败的语句。

      这并不是真正的直接答案,但据我所知,我认为没有办法为异常断点创建异常。希望对你有帮助

      【讨论】:

      • 瑞恩,感谢您的回答!这是一个很好的解决方案,但是,在 Sim 或 Device 上执行应用程序时,异常断点非常有用。理想情况下运行时应该有一组断点,测试时应该有一组断点,有没有办法这样设置?
      【解决方案3】:

      我遇到了同样的问题,我花了 2 个小时寻找解决方案。可能我们对此无能为力。

      【讨论】:

        猜你喜欢
        • 2015-09-11
        • 1970-01-01
        • 2018-09-22
        • 2013-07-20
        • 2019-04-29
        • 2012-07-15
        • 2011-05-22
        • 2013-09-28
        • 2011-04-30
        相关资源
        最近更新 更多