Lis*_*saD 30 xcode unit-testing
我正在编写我的第一个iOS单元测试(Xcode 5,iOS 6),并发现单元测试的结果取决于我最近在模拟器中所做的事情.例如,我点击模拟器中联系人列表中的用户,现在我在UserDefaults中的"最近联系人"数据还有一个比以前更多的对象,即使我正在运行单元测试.
对于单元测试,使用随机用户默认数据并不干净(我习惯使用自己的干净数据库进行RoR测试).此外,我可能想测试特定的状态,比如拥有空的"最近的联系人"数据.
从这里查看相关问题,我似乎有些可能的答案,我不满意.
对于在单元测试中应该是标准做法的东西,这些似乎不必要地复杂化.我不想在每个单元测试中重复自己.所以,我的问题是:
ork*_*den 44
使用像这个答案中的命名套件对我来说效果很好.删除用于测试的用户默认值也可以在中进行func tearDown().
class MyTest : XCTestCase {
var userDefaults: UserDefaults?
let userDefaultsSuiteName = "TestDefaults"
override func setUp() {
super.setUp()
UserDefaults().removePersistentDomain(forName: userDefaultsSuiteName)
userDefaults = UserDefaults(suiteName: userDefaultsSuiteName)
}
}
Run Code Online (Sandbox Code Playgroud)
big*_*gkm 21
适用于iOS 7/10.9
您可以使用套件名称来加载测试,而不是使用standardUserDefaults
[[NSUserDefaults alloc] initWithSuiteName:@"SomeOtherTests"];
Run Code Online (Sandbox Code Playgroud)
这与一些代码相结合,从相应的目录中删除SomeOtherTests.plist文件setUp将归档所需的结果.
您必须设计任何对象来获取默认对象,以便测试不会产生任何副作用.
Rob*_*ier 15
正如@Till建议的那样,您的设计可能不正确,可测试性良好.NSUserDefaults它们不应该直接读取系统的单元可测试部分,而应该使用其他一些对象(可以与之交谈NSUserDefaults).这大致相当于"模拟NSUserDefaults",但实际上是一个额外的抽象层.您的配置对象将抽象两者NSUserDefaults和其他配置存储(如钥匙串).它还可以确保您不会在程序周围散布字符串常量.我为很多项目构建了这种配置对象,并强烈推荐它.
有些人认为单元可测试的对象不应该依赖于像NSUserDefaults我这样推荐的全局"配置"对象的单身人士.相反,所有配置都应该在init注入.在实践中,我发现在与Storyboard交互时会产生太多的麻烦,但是在有用的地方值得考虑.
如果你真的想深入挖掘NSUserDefaults,它确实提供了一些分层功能.您可以调查setVolatileDomain:forName:一下,看看是否可以为单元测试创建额外的图层.在实践中,我对iOS上的这些事情并没有太多的好运(更多的是在Mac上,但仍然没有达到你需要信任它的水平).
它可能是混合standardUserDefaults,但如果你能避免它,我不会推荐这种方法.如果您无法调整设计以避免外部性,那么"开始时保存所有内容并最终恢复所有内容"可能是解决问题的最佳标准化方法.
我喜欢创建一个新的,所以没有冲突
import XCTest
extension UserDefaults {
private static var index = 0
static func createCleanForTest(label: StaticString = #file) -> UserDefaults {
index += 1
let suiteName = "UnitTest-UserDefaults-\(label)-\(index)"
UserDefaults().removePersistentDomain(forName: suiteName)
return UserDefaults(suiteName: suiteName)!
}
}
class MyTest: XCTestCase {
func testOne() {
let userDefaults = UserDefaults.createCleanForTest()
XCTAssertFalse(userDefaults.bool(forKey: "foo"))
userDefaults.set(true, forKey: "foo")
XCTAssertTrue(userDefaults.bool(forKey: "foo"))
}
func testTwo() {
let userDefaults = UserDefaults.createCleanForTest()
XCTAssertFalse(userDefaults.bool(forKey: "foo"))
userDefaults.set(true, forKey: "foo")
XCTAssertTrue(userDefaults.bool(forKey: "foo"))
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11940 次 |
| 最近记录: |