Code Coverage是一个计算你的单元测试覆盖率的工具。高水平的覆盖给你的单元测试带来信心,也表明你的应用被彻底地测试过了。你可能写了几千个单元测试,但如果覆盖率不高,那么你写的这套测试可能价值也不大。
这里并没有一个确切的百分比,要求你必须到达这个覆盖率。这很大程度上取决于你的项目(需依据具体情况分析)。譬如说,如果你的项目中有很多不能写单元测试的视觉组件,那么覆盖率就会比单纯处理数据的框架要低的多。
Code Coverage in Xcode
在过去,如果你想要制作一个测试的代码覆盖报告出来,需要设置很多[选项]。不仅非常复杂,还有许多需要手动设置。在iOS 9中,苹果提供了智能的代码覆盖工具,它是和LLVM一体的,每次运行测试都会被调用和计算。
Using the Code Coverage Tools
现在我们用一个例子来展示,如何使用新的Code Coverage工具和怎样提升现在的测试用例。完成后的代码放在了Github上,你可以跟着做。
第一件事是创建一个新项目,并确认你选上了Unit tests选项。这会按要求创建一个默认项目,现我们需要测试点什么。这个测试可能是你的任意需求,这里我添加一个空的swift文件,里面写好了一个全局的方法。这个方法检测两个字母串是否是仅排序不同的相同字母组成的词。写成全局的方法,可能不是好的设计,但这里我们仅演示一下。
这是一个相对简单的方法,所以我们可能会得到一个没有任何问题的、100%覆盖的测试覆盖率。
func checkWord(word: String, isAnagramOfWord: String) -> Bool {
    // Strip the whitespace and make both of the strings lowercase
    let noWhitespaceOriginalString = word.stringByReplacingOccurrencesOfString(" ", withString: "").lowercaseString
    letnoWhitespaceComparisonString= isAnagramOfWord.stringByReplacingOccurrencesOfString(" ", withString: "").lowercaseString
    // If they have different lengths, they are definitely not anagrams
    if noWhitespaceOriginalString.characters.count != noWhitespaceComparisonString.characters.count {
        return false
    }
    // If the strings are the same, they must be anagrams of each other!
    if noWhitespaceOriginalString == noWhitespaceComparisonString {
        return true
    }
    // If they have no content, default to true.
    if noWhitespaceOriginalString.characters.count == 0 {
        return true
    }
    var dict = [Character: Int]()
    // Go through every character in the original string.
    for index in 1...noWhitespaceOriginalString.characters.count {
        // Find the index of the character at position i, then store the character.
        let originalWordIndex = advance(noWhitespaceOriginalString.startIndex, index - 1)
        let originalWordCharacter = noWhitespaceOriginalString[originalWordIndex]
        // Do the same as above for the compared word.
        let comparedWordIndex = advance(noWhitespaceComparisonString.startIndex, index - 1)
        let comparedWordCharacter = noWhitespaceComparisonString[comparedWordIndex]
        // Increment the value in the dictionary for the original word character. If it doesn't exist, set it to 0 first.
        dict[originalWordCharacter] = (dict[originalWordCharacter] ?? 0) + 1
        // Do the same for the compared word character, but this time decrement instead of increment.
        dict[comparedWordCharacter] = (dict[comparedWordCharacter] ?? 0) - 1
    }
    // Loop through the entire dictionary. If there's a value that isn't 0, the strings aren't anagrams.
    for key in dict.keys {
        if (dict[key] != 0) {
            return false
        }
    }
// Everything in the dictionary must have
een 0, so the strings are balanced.
    return true
}
一旦你写好了算法,就该写个测试了。打开项目创建时已经创建好了的默认的XCTestCase,添加一个下面的简单的测试方法。它看起来是这样子的:
class CodeCoverageTests: XCTestCase {
    func testEqualOneCharacterString() {
        XCTAssert(checkWord("1", isAnagramOfWord: "1"))
    }
}