MetovaTestKit 2.3.1

MetovaTestKit 2.3.1

Chris DillardLogan GauthierNick GriffithChris MartinBeverly MassengillMetova, Inc.维护。



  • Metova, Inc.、Nick Griffith、Logan Gauthier和Chris Martin出品

MetovaTestKit

Build Status CocoaPods Compatible Documentation Coverage Status Platform Twitter

MetovaTestKit是一组用于简化iOS应用程序测试编写负担的有用测试助手。


要求

  • Swift 4.0
  • iOS 9+

安装

MetovaTestKit可通过CocoaPods获取。

MetovaTestKit旨在与单元测试目标一起使用。要安装它,将MetovaTestKit添加到您的项目的Podfile中

target 'YourApp' do
  # Your app's pods:
  pod 'DataManager'
  pod 'ThunderCats'
  pod 'MetovaBase'

  target 'YourAppTests' do
    inherit! :search_paths
    pod 'MetovaTestKit'
  end
end

然后运行pod install

如果您想测试MetovaTestKit的beta版本,您可以安装最新的develop版本

pod 'MetovaTestKit', :git => 'https://github.com/metova/MetovaTestKit.git', :branch => 'develop'

使用方法

MTKTestable

MetovaTestKit 定义了 MTKTestable 协议。该协议的正确定义可以实现功能性单元测试。它通过将设置和清理代码抽象为你要测试的类型扩展来实现这一点,并允许进行功能性单元测试。

func testOutlets() {
    HomeViewControllerClass.test { testVC in
        XCTAssertNotNil(testVC.userameTextField)
        XCTAssertNotNil(testVC.passwordTextField)
        XCTAssertNotNil(testVC.loginButton)
    }
}

test 函数会重新抛出在 testBlock 内部抛出的任何错误,这样你可以方便地通过抛出测试用例来表示失败。

func testLogin() throws {
    try HomeViewControllerClass.test { testVC in
        try testVC.login(username: "jimmythecorgi", password: "woofwoof123")
    }
}

测试 UIKit 组件

UIAlertController

验证显示的 alert 是否具有特定的样式、标题、消息和操作。

MTKAssertAlertIsPresented(
    by: testVC,
    style: .alert,
    title: "Warning",
    message: "Are you sure you want to delete this user?",
    actions: [
        ExpectedAlertAction(title: "Delete", style: .destructive),
        ExpectedAlertAction(title: "Cancel", style: .cancel)
    ]
)

UIBarButtonItem

验证 bar button item 是否具有预期的目标/操作对,并且目标确实响应将发送给它的事件。

MTKAssertBarButtonItem(testVC.editBarButtonItem, sends: #selector(MyViewController.didTapEditButton(_:)), to: testVC) 

UIControl

您可以用一个断言来验证您的控件动作是否连接,以及目标是否响应将发送事件的选择器。

MTKAssertControl(testVC.loginButton, sends: #selector(LoginViewController.didTapLoginButton(_:)), to: testVC, for: .touchUpInside, "The login button should be hooked up to the login action.") 

UICollectionViewCell

断言集合视图对于给定的索引路径返回特定类型的单元格。如果单元格存在,传递一个代码块进行额外的测试。

MTKTestCell(in: tableView, at: indexPath, as: MyCollectionViewCell.self) { testCell in 
    XCTAssertEqual(testCell.label.text, "Hello World!")
}

参阅 测试示例,了解此方法可以生成测试失败的示例。

UITableViewCell

断言一个表格视图对一个特定的索引路径返回特定类型的单元。

MTKTestCell(in: tableView, at: indexPath, as: MyTableViewCell.self) { testCell in
    XCTAssertEqual(testCell.label.text, "Hello World!")
}

参见 测试,了解此方法可以生成的测试失败示例。

UISegmentedControl

验证UISegmentedControl具有您期望的分段标题。

MTKAssertSegmentedControl(segmentedControl, hasSegmentTitles: ["Followers", "Following"])

测试日期

您可以使用MetovaTestKit断言两个日期在仅考虑指定的组件时相等。

MTKAssertEqualDates(date1, date2, comparing: .year, .month, .day)

此断言接受组件作为可变参数或作为Set<Calendar.Component>

let components: Set<Calendar.Component> = [.year, .month, .day, .hour, .minute, .second]
MTKAssertEqualDates(date1, date2, comparing: components)
MTKAssertEqualDates(date3, date4, comparing: components)
MTKAssertEqualDates(date5, date6, comparing: components)

测试自动布局约束

您可以使用MetovaTestKit断言您没有损坏自动布局约束。

MTKAssertNoBrokenConstraints {
    // code that does anything that impacts the user interface
    // including simply loading a view for the first time
}

如果存在损坏的约束,此断言将失败,并报告测试期间损坏的约束数量。您还可以传递自定义消息。

MTKAssertNoBrokenConstraints(message: "Constraints were broken.") {
    // code to test
}

此测试还返回一个值,带有损坏的约束计数。

let brokenConstraintCount = MTKAssertNoBrokenConstraints {
    // code to test
}

测试异常

您可以使用MetovaTestKit断言不应该抛出异常的代码没有抛出。在没有MetovaTestKit的情况下,这将导致整个测试套件崩溃。有了MetovaTestKit,这只是一件失败的测试,您仍然可以运行其他测试。

MTKAssertNoException {
    // code that should not throw exceptions
    // results in passing test if no exceptions are thrown
    // results in failing test if exceptions are thrown
}

您还可以传递一条消息来在失败时打印。

MTKAssertNoException(message: "Exception was thrown.") {
    // code that should not throw exceptions
    // results in passing test if no exceptions are thrown
    // results in failing test if exceptions are thrown
}

您还可以测试代码来验证是否抛出异常,并且可以在不使测试套件崩溃的情况下进行此操作。如果您对具体的异常不感兴趣,只想验证代码块是否抛出异常,您可以使用 MTKAssertException

MTKAssertException {
    // code that should throw exceptions
    // results in passing test if an exception is thrown
    // results in a failing test if this closure returns without throwing
}

MTKAssertNoException 类似,此函数也接受一条消息

MTKAssertException(message: "No exception was thrown.") {
    // code that should throw exceptions
    // results in passing test if an exception is thrown
    // results in a failing test if this closure returns without throwing
}

这些方法确实在您需要更多有关异常的信息时返回抛出的异常。

guard let exception = MTKAssertException(testBlock: throwingBlock) else {
    XCTFail("Block failed to throw an exception")
    return
}

// More assertion about the given exception that was returned
if let exception = MTKAssertNoException(testBlock: blockThatShouldntThrow) {
    XCTFail("Block should not have thrown but instead threw \(exception)")
    return
}

如果闭包没有抛出异常,函数返回 nil。否则,它返回一个 NSException 实例,您可以验证您的代码块是否抛出了预期的异常。

异步测试

XCTest 使用 expectation(description:)waitForExpectations(timeout:handler:) 提供异步测试功能。然而,当测试简单的延迟异步操作时,这种方法可能会很繁琐,意图可能并不立即明显。使用 MetovaTestKit 的 MTKWaitThenContinueTest(after:) 工具方法,这些类型的测试变得简单,而且读起来很自然。

mockUserSearchNetworkRequest(withResponseTime: 0.5)
testViewController.didTapSearchButton()
 
XCTAssertFalse(testViewController.searchButton.isEnabled, "The search button should be disabled while a search request is taking place.")
 
MTKWaitThenContinueTest(after: 1)
 
XCTAssertTrue(testViewController.searchButton.isEnabled, "Once the request is complete, the search button should be re-enabled.") 

文档

文档可在此处找到 http://metova.github.io/MetovaTestKit/.


致谢

MetovaTestKit 由 Metova Inc. 拥有和维护。

贡献者

如果您想为 MetovaTestKit 贡献,请参阅我们的 贡献指南

MetovaTestKit 标题图像和其他资产由 Christi Johnson 提供。


许可

MetovaTestKit 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。