Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift-单元测试专用变量和方法_Swift_Unit Testing - Fatal编程技术网

Swift-单元测试专用变量和方法

Swift-单元测试专用变量和方法,swift,unit-testing,Swift,Unit Testing,我正在试着测试一门课,但我有点搞不清楚该测试什么。下面是我想进行单元测试的类: class CalculatorBrain { private var accumulator = 0.0 func setOperand(operand: Double) { accumulator = operand } var result: Double { return accumulator } private var

我正在试着测试一门课,但我有点搞不清楚该测试什么。下面是我想进行单元测试的类:

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
        }
    }
}
class CalculatorBrain{
专用var累加器=0.0
func集合操作数(操作数:双精度){
累加器=操作数
}
var结果:双{
回流蓄能器
}
私有变量操作:字典=[
“=”:。等于,
“π”:.常数(M_π),
“e”:.常数(M_e),
“±”:.UnaryOperation({(op1:Double)->返回双精度-op1}),
"√" : .一元操作(sqrt),
“cos”:.一元操作(cos),
“+”:.BinaryOperation({(op1:Double,op2:Double)->Double返回op1+op2}),
"−:.BinaryOperation({(op1:Double,op2:Double)->返回op1-op2}中的Double),
“×”:.BinaryOperation({(op1:Double,op2:Double)->返回op1*op2}中的Double),
“÷”:.BinaryOperation({(op1:Double,op2:Double)->返回op1/op2}中的Double)
]
私有枚举操作{
案例常数(双)
案例一元运算((双)->双)
case二进制操作((双精度,双精度)->Double)
大小写相等
}
func性能操作(符号:字符串){
如果let操作=操作[符号]{
开关操作{
案例常数(let值):
累加器=值
一元运算(let函数):
累加器=功能(累加器)
case.BinaryOperation(let函数):
executePendingBinaryOperation()
pendingBinaryOperation=PendingBinaryOperationInfo(binaryOperation:函数,第一个操作数:累加器)
案例。等于:
executePendingBinaryOperation()
}
}
}
私有变量pendingBinaryOperation:PendingBinaryOperationInfo?
私有结构PendingBinaryOperationInfo{
var二进制操作:(双精度,双精度)->Double
var第一个操作数:双精度
}
私有func executePendingBinaryOperation(){
如果let pending=pendingBinaryOperation{
累加器=pending.binaryOperation(pending.FirstOperator,累加器)
pendingBinaryOperation=nil
}
}
}
对于上面的代码,什么是好的测试

是否值得测试字典
operations
中的每个操作(+、-、*、/,等等)


值得测试私有方法吗?

单元测试应该被视为黑盒测试,这意味着您不关心您测试的单元的内部。您主要感兴趣的是根据您在单元测试中给出的输入来查看单元输出是什么

现在,通过输出,我们可以断言以下几点:

  • 方法的结果
  • 作用于对象后的对象状态
  • 与对象具有的依赖项的交互
在所有情况下,我们只对公共接口感兴趣,因为它是与世界其他地方进行通信的接口

私有的东西不需要单元测试,因为任何私有的项目都被公共的项目间接使用。诀窍是编写足够的测试来锻炼公共成员,这样私有的项目就被完全覆盖了

另外,需要记住的一件重要事情是,单元测试应该验证单元规范,而不是其实现。验证实现细节会在单元测试代码和被测试代码之间增加紧密耦合,这有一个很大的缺点:如果被测试的实现细节发生变化,那么单元很可能会est也需要更改


以黑盒方式编写单元测试意味着您可以重构这些单元中的所有代码,而无需担心更改测试可能会在单元测试代码中引入错误。不可靠的单元测试有时比缺少测试更糟糕,因为给出误报的测试可能会隐藏实际错误您的代码中存在错误。

您不能使用
@testable
在Swift中测试私有方法。您只能测试标记为
internal
public
的方法。正如文档所述:

注:@testable仅为“内部”功能提供访问权限; “private”声明在其文件外不可见,即使在 使用@testable

阅读更多内容

我发现这与克里斯蒂克的说法类似


基本上,您提出的问题是错误的,您不应该试图测试标记为“private”的类/函数。

尽管我同意不测试
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 Diego's answer is clever but it is possible to go further.

  1. Go into your project editor and define a new Testing Configuration by duplicating the Debug configuration.
  2. Edit your scheme's Test action so that the build configuration is Testing.
  3. Now edit your test target's build settings to define an additional Active Compilation Conditions value for the Testing configuration,
    "TESTING"
    .
Now you can say
#if TESTING
, as distinct from mere
DEBUG
.

I use this, for example, to declare initializers that only a test can see.

I think actually don’t need to test of private members. But if you want to use to
private
members(properties & methods) at
UnitTest
, there is a way that use
Protocol
.

Protocol PrivateTestable {
  associatedtype PrivateTestCase  
  var privateTestCase: PrivateTestCase {get}
}
<代码>导入基础 公开课考试{ 内部函数testInternal()->Int{ 返回1 } public func testPublic()->Int{ 返回2 } //我们不能测试这个! private func testPrivate()->Int{ 返回3 } } //由于#if DEBUG,无法随生产代码一起提供
//加上一句很好的评论:“为什么需要这样做Diego的回答很聪明,但可以更进一步

  • 进入项目编辑器,通过复制调试配置定义新的测试配置
  • 编辑方案的测试操作,以便生成配置正在测试
  • 现在编辑测试目标的生成设置,为测试配置定义一个附加的活动编译条件值,
    “Testing”
  • 现在,您可以说“如果测试”
    ,而不仅仅是“调试”


    例如,我使用它来声明只有测试才能看到的初始值设定项。

    我认为实际上不需要测试私有成员。 但是如果你想使用
    private