我真的很难理解单元测试.我确实理解TDD的重要性,但我读到的所有单元测试的例子似乎都非常简单和微不足道.例如,测试以确保设置属性或将内存分配给数组.为什么?如果我编码..alloc] init]
,我真的需要确保它有效吗?
我是开发新手,所以我肯定我在这里缺少一些东西,特别是围绕TDD的所有热潮.
我认为我的主要问题是我找不到任何实际的例子.这是一种setReminderId
似乎很适合测试的方法.什么是有用的单元测试看起来确保这是有效的?(使用OCUnit)
- (NSNumber *)setReminderId: (NSDictionary *)reminderData
{
NSNumber *currentReminderId = [[NSUserDefaults standardUserDefaults] objectForKey:@"currentReminderId"];
if (currentReminderId) {
// Increment the last reminderId
currentReminderId = @(currentReminderId.intValue + 1);
}
else {
// Set to 0 if it doesn't already exist
currentReminderId = @0;
}
// Update currentReminderId to model
[[NSUserDefaults standardUserDefaults] setObject:currentReminderId forKey:@"currentReminderId"];
return currentReminderId;
}
Run Code Online (Sandbox Code Playgroud) 你如何编写第一响应者单元测试?
我正在尝试编写测试以确认方法将焦点提升到下一个文本字段.controller
是...的后代UIViewController
.但是这个探索性测试失败了:
- (void)testFirstResponder
{
[controller view];
[[controller firstTextField] becomeFirstResponder];
STAssertTrue([[controller firstTextField] isFirstResponder], nil);
}
Run Code Online (Sandbox Code Playgroud)
第一行导致视图被加载,以便其出口就位.文本字段是非零的.但测试从未通过.
我猜测becomeFirstResponder
不会立即设置第一个响应者,而是将其安排在以后.那么有一个很好的方法来编写单元测试吗?
在接受的答案中从评论中提取答案......让事情运行一小段时间:
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];
Run Code Online (Sandbox Code Playgroud)
我还发现我需要创建一个UIWindow并将视图控制器的视图放入其中,如最热门的答案中所述.
在Xcode中,在我的单元测试结束时,我得到如下结果:
测试套件'所有测试'在2012-12-06 10:23:38 +0000完成
执行195次测试,在4.314(4.485)秒内有0次失败(0次意外)
我很想知道如何定义具有预期故障的测试.
通常使用其他测试框架,我希望能够将不完整的单元测试定义为必须完成的未来工作的提醒.这些测试应仅作为警告记录,但如果其他一切正常,仍会产生"成功"最终结果
看看Xcode的输出,我假设有一种方法可以达到同样的效果.但是,我在找到正确的宏来标记不完整/ TODO测试时遇到问题.此外,我觉得正常的失败报告为:
执行了95次测试,在2.314(2.334)秒内出现1次失败(0次意外)
因此,任何测试断言似乎都是预期的.在那种情况下,我甚至对(0个意外)失败的含义感到困惑.
任何人都可以解释这部分日志结果的含义吗?如何使用它?我怎样才能标记不完整的测试?
我目前正在使用
addUIInterruptionMonitor(withDescription: "System alerts") { alert in
let notNowButton = alert.buttons["Not Now"]
if notNowButton.exists {
notNowButton.tap()
return true
}
return false
}
Run Code Online (Sandbox Code Playgroud)
消除在执行 ui 测试期间显示的系统警报,但以下“表”不被识别为警报,我无法消除它。
我已经使用 xcode 中的“记录”按钮来获取“现在不”按钮的 ui 坐标:
app.scrollViews.otherElements.buttons["Not now"].tap()
Run Code Online (Sandbox Code Playgroud)
我在 Xcode 14.3 中遇到了与上述工作表相关的问题。有没有解决方案可以在执行过程中消除这些系统“表”?
通常当我想将标签移动到右侧20px,或仅增加视图的宽度时,我会通过以下一个途径
label.frame = CGRectMake(label.frame.origin.x+20, label.frame.origin.y, label.frame.size.width, label.frame.size.height);
Run Code Online (Sandbox Code Playgroud)
要么
CGRect viewFrame = view.frame;
viewFrame.x += 20;
view.frame = viewFrame;
Run Code Online (Sandbox Code Playgroud)
我并不特别喜欢变化中的代码量,并且希望你们知道我没有发现的捷径
有没有办法忽略特定的测试用例而不将其评论出来?
有些测试是在实现存在之前编写的,所以在提交任何代码之前,我想先将这些测试标记为忽略,这样就不会给任何同事带来任何影响.
对它们进行评论会导致失败,不完整的测试失败.
在OCMockito中,使用NSProxy实现测试双精度.实例中的双重实现-respondsToSelector:
如下:
- (BOOL)respondsToSelector:(SEL)aSelector {
return [_mockedClass instancesRespondToSelector:aSelector];
}
Run Code Online (Sandbox Code Playgroud)
但是对于一个类的实现-respondsToSelector:
这样的双重实现:
- (BOOL)respondsToSelector:(SEL)aSelector {
return [_mockedClass respondsToSelector:aSelector];
}
Run Code Online (Sandbox Code Playgroud)
这一切都适用于32位运行时.例如,如果_mockedClass
是[NSString class]
,则代理正确回答它响应选择器+pathWithComponents:
但在64位运行时,它崩溃了:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Application Specific Information:
objc[1868]: GC: forcing GC OFF because OBJC_DISABLE_GC is set
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x00007fff95cbffc6 cache_getImp + 6
1 libobjc.A.dylib 0x00007fff95ccd1dc lookUpImpOrForward + 50
2 libobjc.A.dylib 0x00007fff95ccd198 lookUpImpOrNil + …
Run Code Online (Sandbox Code Playgroud) 我正在使用OCMockito,我想在我的ViewController中测试一个使用NetworkFetcher对象和块的方法:
- (void)reloadTableViewContents
{
[self.networkFetcher fetchInfo:^(NSArray *result, BOOL success) {
if (success) {
self.model = result;
[self.tableView reloadData];
}
}];
}
Run Code Online (Sandbox Code Playgroud)
特别是,我想要模拟,fetchInfo:
以便它返回一个虚拟result
数组而不会访问网络,并验证该reloadData
方法是否被调用,UITableView
并且模型应该是它应该是什么.
由于此代码是异步的,我假设我应该以某种方式捕获块并从我的测试中手动调用它.
我怎么能做到这一点?
在这里,我尝试检查视图控制器的单元测试用例。- 我有一个带有按钮和标签的视图控制器。- 当您单击按钮时,它将调用另一个方法。它将数据提供给按钮操作标签文本更改。
- 我想检查该按钮是否触发了该方法?无需添加函数的任何布尔值或返回类型。
这是我的代码。
class ViewController: UIViewController {
@IBOutlet weak var buttonFetch: UIButton?
@IBOutlet weak var nameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func fetchUser() {
self.nameLabel.text = self.getUser()
}
func getUser() ->String {
return User.data()
}
}
struct User {
static func data()->String{
return "Apple"
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试用例
func testFetchUserAction() {
controller.buttonFetch?.sendActions(for: .touchDown)
// I want to test the method getUser from viewcontroller gets called or not
// some thing like this XCTAssert(self.controller.getUser(),"not called")
XCTAssertEqual(self.controller.nameLabel.text!, …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个 UI 测试用例,我需要在其中执行一个操作,然后在当前页面上,将唯一的滚动UITableView
到底部以检查特定文本是否显示在UITableView
.
现在我能想到的唯一方法是使用 滚动它app.tables.cells.element(boundBy: 0).swipeUp()
,但是如果单元格太多,它不会一直滚动到底部。并且 中的单元格数量UITableView
并不总是相同,我不能向上滑动不止一次,因为表格中可能只有一个单元格。
ios ×5
ocunit ×4
unit-testing ×4
objective-c ×3
xcode ×3
swift ×2
testing ×2
xctest ×2
xcuitest ×2
class-method ×1
cocoa ×1
cocoa-touch ×1
iphone ×1
nsproxy ×1
ochamcrest ×1
ocmockito ×1
passwords ×1
tdd ×1
uitableview ×1
uitest ×1
xctestcase ×1