bre*_*top 36 unit-testing swift
我正在尝试测试一个课程,但我对测试什么感到困惑.这是我要进行单元测试的类:
class CalculatorBrain {
private var accumulator = 0.0
func setOperand(operand: Double) {
accumulator = operand
}
var result: Double {
return accumulator
}
private var operations: Dictionary<String, Operation> = [
"=" : .Equals,
"?" : .Constant(M_PI),
"e" : .Constant(M_E),
"±" : .UnaryOperation({ (op1: Double) -> Double in return -op1 }),
"?" : .UnaryOperation(sqrt ),
"cos": .UnaryOperation(cos),
"+" : .BinaryOperation({ (op1: Double, op2: Double) -> Double in return op1 + op2 }),
"?" : .BinaryOperation({ (op1: Double, op2: Double) -> Double in return op1 - op2 }),
"×" : .BinaryOperation({ (op1: Double, op2: Double) -> Double in return op1 * op2 }),
"÷" : .BinaryOperation({ (op1: Double, op2: Double) -> Double in return op1 / op2 })
]
private enum Operation {
case Constant(Double)
case UnaryOperation((Double) -> Double)
case BinaryOperation((Double, Double) -> Double)
case Equals
}
func performOperation(symbol: String) {
if let operation = operations[symbol] {
switch operation {
case .Constant(let value):
accumulator = value
case .UnaryOperation(let function):
accumulator = function(accumulator)
case .BinaryOperation(let function):
executePendingBinaryOperation()
pendingBinaryOperation = PendingBinaryOperationInfo(binaryOperation: function, firstOperand: accumulator)
case .Equals:
executePendingBinaryOperation()
}
}
}
private var pendingBinaryOperation: PendingBinaryOperationInfo?
private struct PendingBinaryOperationInfo {
var binaryOperation: (Double, Double) -> Double
var firstOperand: Double
}
private func executePendingBinaryOperation() {
if let pending = pendingBinaryOperation {
accumulator = pending.binaryOperation(pending.firstOperand, accumulator)
pendingBinaryOperation = nil
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于上面的代码,什么是好的测试.
是否值得测试字典中的每一个操作(+, - ,*,/等)operations?
是否值得测试私有方法?
Cri*_*tik 23
根据定义,单元测试是黑盒测试,这意味着您不关心您测试的单元的内部.您主要想知道基于您在单元测试中给出的输入的单位输出是什么.
现在,通过输出,我们可以断言几件事:
在所有情况下,我们只对公共界面感兴趣,因为那是与世界其他地方进行通信的界面.
私有东西不需要单独测试,因为任何私有项目都是由公共项目间接使用的.诀窍是编写足够的测试来锻炼公众成员,以便完全覆盖私人成员.
另外,要记住的一件重要事情是单元测试应该验证单元规范,而不是它的实现.验证实现细节会增加单元测试代码和测试代码之间的紧密耦合,这有一个很大的缺点:如果测试的实现细节发生变化,那么单元测试也可能需要更改,这会降低对该段代码进行单元测试.
Die*_*che 11
虽然我同意不测试private内容,我宁愿只测试公共接口,但有时候我需要在隐藏的类中测试一些内容(比如复杂的状态机).对于这些情况,您可以做的是:
import Foundation
public class Test {
internal func testInternal() -> Int {
return 1
}
public func testPublic() -> Int {
return 2
}
// we can't test this!
private func testPrivate() -> Int {
return 3
}
}
// won't ship with production code thanks to #if DEBUG
// add a good comment with "WHY this is needed "
#if DEBUG
extension Test {
public func exposePrivate() -> Int {
return self.testPrivate()
}
}
#endif
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
import XCTest
@testable import TestTests
class TestTestsTests: XCTestCase {
func testExample() {
let sut = Test()
XCTAssertEqual(1, sut.testInternal())
}
func testPrivateExample() {
let sut = Test()
XCTAssertEqual(3, sut.exposePrivate())
}
}
Run Code Online (Sandbox Code Playgroud)
我完全理解这是一个黑客.但知道这个技巧可以在未来保存你的培根.不要滥用这个技巧.
迭戈的回答很聪明,但还有可能走得更远。
"TESTING"。现在可以说#if TESTING,有别于单纯DEBUG。
例如,我使用它来声明只有测试才能看到的初始值设定项。
| 归档时间: |
|
| 查看次数: |
19948 次 |
| 最近记录: |