IBA和IBOutlets Swift的XCT测试(可选项)

时间:2015-08-05 11:35:42

标签: swift unit-testing optional xctest

我想知道由于IBActions是Optionals,在Swift中测试IBOutlets和IBActions的最佳方法是什么。

我目前正在重写我最初在Swift中编写的项目,但这次我想使用XCT单元测试。

我已经遇到了关于IBOutlets和IBActions测试的小问题。这是我的代码:

override func setUp() {
    super.setUp()

    storyboard = UIStoryboard(name: "Main", bundle: nil)
    mainMenuViewController = storyboard.instantiateViewControllerWithIdentifier("MainMenuViewController") as! MainMenuViewController

    let dummy = mainMenuViewController.view // force loading subviews and setting outlets

    mainMenuViewController.viewDidLoad()
}

override func tearDown() {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    super.tearDown()
}

func testWhetherTranslationGameModeButtonExists() {
    XCTAssert(mainMenuViewController.translateButton != nil, "translate button should exist at all times");
}

func testWhetherTranslateGameModeButtonTitleIsCorrect() {

    let title: String? = mainMenuViewController.translateButton?.titleLabel?.text

    if let unwrappedTitle = title {
        XCTAssertTrue(unwrappedTitle == "Translate Mode", "title of translate button should be Translate Mode")
    }
    else {
        XCTFail("Value isn't set")
    }
}

func testTranslateGameModeButtonIBAction() {

    if let unwrappedButton = mainMenuViewController.translateButton {
        if let actions: Array<String> = unwrappedButton.actionsForTarget(mainMenuViewController, forControlEvent: UIControlEvents.TouchUpInside) as? Array<String> {

            contains(actions, "")
            XCTAssertTrue(contains(actions, "translateButtonPressed"), "translate button should call method translateButtonPressed")
        }
        else {
            XCTFail("button is set but the IBAction is not set")
        }
    }
    else {
        XCTFail("button isn't set and therefore IBAction can not function")
    }
}

如您所见,第一个测试检查翻译游戏模式按钮是否存在。这很好用。

然而,通过标题测试,我需要打开按钮然后测试标签。这似乎是两个测试中的一个。

对于IBAction,我有同样的问题。我需要打开可选类型以使用该按钮,并为成功和失败提供XCTAssert。因此,每次我使用此按钮时,我都需要先打开它才能使用它。这似乎是非常重复的,并且似乎又在一个中进行了多次测试。

我想知道这是否是正确的方法,还是有更好的方法来接近选项的测试。

2 个答案:

答案 0 :(得分:0)

如果可能,请转到XCode 7。 使用XCode 7,您可以轻松地进行UI测试:

档案 - &gt;新的 - &gt;目标 - &gt; iOS - &gt;测试iOS UI测试包

生成的代码有一些提示如何使用它。基本上,您将光标放在测试方法中,然后点击红色记录按钮。

因此,您可以模拟(几乎)任何用户操作。当您为可访问性命名UI元素时,生成的代码更具可读性。

您的测试结果更有意义,因为您在自然栖息地中测试您的控制器:在您的应用程序内。

(在XCode 7之前已经可以使用XCode 7,但这很容易)

答案 1 :(得分:0)

我不明白为什么你的按钮是可选的。 如果通过拖动在控制器中创建插座,则会得到一个非可选变量

我正在设置我的Controller测试,如下所示: https://gist.github.com/racer1988/bf15448efde47e627dac

我接受了这个想法: http://natashatherobot.com/ios-testing-view-controllers-swift/

然后为了完成覆盖,你要编写3个测试:

  • 如果设置了插座
  • 如果出口连接到某个动作
  • 如果行动正在履行职责

通过这种方式,您可以测试所有内容,而无需伪造水龙头或类似的东西

func testOutletExist() {
    XCTAssertNotNil(viewController.outletName)
}

func testActionIsConnected() {
    XCTAssertTrue(viewController.outlet.action == "IBactionName:")
}

func testActionCode() {
    let result = IBactionName()
    XCTAssertSomething(result)
}