我们在项目中跟踪an issue我们会间歇性地失败快照测试用例。我们的方法的要点是渲染视图控制器的视图,并将该图像与参考图像进行比较,以查看它们是否不同。我们的方法有几个层次:
我们的问题是,有时渲染视图创建的图像为空。只是一个大的(正确大小)透明图像。
我已经孤立地对每一个进行了测试,并确定这些都不是问题所在。相反,我已经能够在独立的普通 Xcode项目中重现这一点。
通过使用FBSnapshotTestCases用于呈现视图的same approach,我创建了一个简单的测试。要重现,请创建一个" Master-Detail"的新项目。模板并为详细视图控制器提供故事板ID"详细信息"。然后创建这个简单的单元测试。
func testExample1() {
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let sut = storyboard.instantiateViewControllerWithIdentifier("Detail") as UIViewController
sut.beginAppearanceTransition(true, animated: false)
sut.endAppearanceTransition()
UIGraphicsBeginImageContextWithOptions(sut.view.frame.size, false, 0)
sut.view.drawViewHierarchyInRect(sut.view.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
let data = UIImagePNGRepresentation(image)
println("byte length: \(data.length)")
}
没什么太花哨的,而且很可能会过去。但是,如果您再复制代码几次:
func testExample1() { ... }
func testExample2() { ... }
func testExample3() { ... }
输出很奇怪(截断):
Test Suite 'All tests' started at 2014-10-02 07:46:52 +0000
byte length: 27760
byte length: 17645
byte length: 27760
Test Suite 'All tests' passed at 2014-10-02 07:55:29 +0000.
Executed 3 tests, with 0 failures (0 unexpected) in 517.778 (517.781) seconds
字节长度应该相同,但它们不相同。第二个测试(有时是第三个测试)将有一个空视图,就像我们的问题一样。
展示问题的示例项目here。
我能够使用Objective-C测试项目重现该问题,因此它不太可能是Swift问题。在过去的项目中,我们还没有将Storyboard用于我们的视图控制器用户界面,因此可能需要额外的步骤以便强制使用#34;要加载的视图。它也可能是Xcode 6.x或iOS 8问题(我已经用Xcode 6.0.1重现了这个问题)。
有没有人遇到这样的问题,从故事板加载的控制器的视图渲染图像是否透明?
答案 0 :(得分:2)
好像有把戏......
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let sut = storyboard.instantiateViewControllerWithIdentifier("Detail") as UIViewController
sut.beginAppearanceTransition(true, animated: false)
sut.endAppearanceTransition()
UIGraphicsBeginImageContextWithOptions(sut.view.frame.size, false, 0)
let context = UIGraphicsGetCurrentContext
sut.view.layer.renderInContext(context())
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let data = UIImagePNGRepresentation(image)
println("byte length: \(data.length)")
答案 1 :(得分:1)
通过切换到生成的UIView来将故事板排除在等式之外:
let view = UIView(frame: CGRectMake(0, 0, 300, 300))
view.backgroundColor = UIColor.blueColor()
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, 0)
view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
let data = UIImagePNGRepresentation(image)
println("byte length: \(data.length)")
给出类似的结果。
Test Case '-[TestTestTests.TestTestTests testExample1]' started.
byte length: 9663
Test Case '-[TestTestTests.TestTestTests testExample1]' passed (1.000 seconds).
Test Case '-[TestTestTests.TestTestTests testExample2]' started.
byte length: 9663
Test Case '-[TestTestTests.TestTestTests testExample2]' passed (0.112 seconds).
Test Case '-[TestTestTests.TestTestTests testExample3]' started.
byte length: 6469
答案 2 :(得分:0)
正如本主题建议您尝试使用" [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]"代替:
drawViewHierarchyInRect:afterScreenUpdates: delays other animations