Unit testing 处理TDD/单元测试疲劳

Unit testing 处理TDD/单元测试疲劳,unit-testing,tdd,code-coverage,Unit Testing,Tdd,Code Coverage,所以我已经习惯了TDD,但我遇到了一个意想不到的问题:我真的厌倦了100%的代码覆盖率。编写测试比编写代码本身更加繁琐,我不确定我是否做对了。我的问题是:你应该测试什么样的东西,什么样的东西是多余的? 例如,我有一个如下的测试,我不确定它是否有用。我该怎么做才能让我仍然遵循TDD,但不会厌倦编写测试 describe 'PluginClass' describe '.init(id, type, channels, version, additionalInfo, functionSo

所以我已经习惯了TDD,但我遇到了一个意想不到的问题:我真的厌倦了100%的代码覆盖率。编写测试比编写代码本身更加繁琐,我不确定我是否做对了。我的问题是:你应该测试什么样的东西,什么样的东西是多余的?

例如,我有一个如下的测试,我不确定它是否有用。我该怎么做才能让我仍然遵循TDD,但不会厌倦编写测试

describe 'PluginClass'

    describe '.init(id, type, channels, version, additionalInfo, functionSource, isStub)'

        it 'should return a Plugin object with correct fields'

            // Create test sets
            var testSets = new TestSets()
            var pluginData = {
                'id'                : null,
                'type'              : null,
                'channels'          : null,
                'version'           : null,
                'additionalInfo'    : null,
                'functionSource'    : null,
                'isStub'            : true
            }
            testSets.addSet({ 'pluginData' : pluginData })
            var pluginData = {
                'id'                : "testPlugin1",
                'type'              : "scanner",
                'channels'          : ['channelA', 'channelB'],
                'version'           : "1.0",
                'additionalInfo'    : {'test' : "testing"},
                'functionSource'    : "function () {alert('hi')}",
                'isStub'            : false
            }
            testSets.addSet({ 'pluginData' : pluginData })

            for (var t = 0; t < testSets.getSets().length; t ++) {
                var aTestSet = testSets.getSet(t)

                var plugin = new Plugin().init( aTestSet.pluginData.id,
                                                aTestSet.pluginData.type,
                                                aTestSet.pluginData.channels,
                                                aTestSet.pluginData.version,
                                                aTestSet.pluginData.additionalInfo,
                                                aTestSet.pluginData.functionSource,
                                                aTestSet.pluginData.isStub  )

                plugin.getID().should.eql aTestSet.pluginData.id
                plugin.getType().should.eql aTestSet.pluginData.type
                plugin.getChannels().should.eql aTestSet.pluginData.channels
                plugin.getVersion().should.eql aTestSet.pluginData.version
                plugin.getAdditionalInfo().should.eql aTestSet.pluginData.additionalInfo
                eval("fn = " + aTestSet.pluginData.functionSource)
                JSON.stringify(plugin.getFunction()).should.eql JSON.stringify(fn)
                plugin.getIsStub().should.eql aTestSet.pluginData.isStub
            }

        end

    end

end
描述“插件类”
描述'.init(id、类型、通道、版本、附加信息、函数源、isStub)'
它“应该返回带有正确字段的插件对象”
//创建测试集
var testSets=newtestsets()
变量pluginData={
“id”:null,
“类型”:null,
“通道”:null,
“版本”:null,
“additionalInfo”:null,
“functionSource”:null,
“isStub”:对
}
addSet({'pluginData':pluginData})
变量pluginData={
'id':“testPlugin1”,
“类型”:“扫描仪”,
“频道”:[“频道A”、“频道B”],
“版本”:“1.0”,
'additionalInfo':{'test':“testing”},
'functionSource':“函数(){alert('hi')}”,
“isStub”:错误
}
addSet({'pluginData':pluginData})
for(var t=0;t
当然,上述“测试”在许多方面都有些过分。它太长太复杂,难以阅读,而且断言的东西太多。我很难想象这是如何从TDD过程中产生的。这并不奇怪,你会厌倦这样的东西

测试驱动开发意味着:您应该分为几个小步骤,每个步骤都是一个单独的测试,只声明一件事,并且绝对不包含任何逻辑(即,对于、
如果/否则
或类似的逻辑…)。因此,上面的代码将产生大约4-6个单独的测试方法,然后您将逐个实现这些方法。首先断言正确的属性初始化(根据需要使用不同的值),然后确保方法按预期工作,依此类推

代码覆盖率指标不会告诉您关于测试的任何信息,除了它可以向您显示任何测试都不会涉及的生产代码。特别是它不会告诉你触摸过的代码是否真的被测试过(不仅仅是触摸过的…)。这只取决于测试的质量。所以,不要把代码覆盖率看得太重,在很多情况下,使用更好的测试来降低覆盖率更可取

总之: 对几乎所有内容都进行测试(100%覆盖率)并不过分,但像您的示例中那样进行测试肯定是一个问题

我建议您回顾一下您的TDD/单元测试实践,这本书可能是一个很好的资源



Thomas

单元测试的目标应该是测试代码中可能包含bug的部分。实现100%的测试覆盖率不应该是一个目标,而且毫无疑问,TDD并没有把它作为一个目标

无论是现在还是随着系统的发展,为不太可能包含重大bug的代码创建详尽的测试都是一种乏味的时间浪费。(在未来,重复的单元测试可能会成为测试本身中无意义回归的来源,而这些回归只会浪费一些人的时间去寻找和修复。)


最后,在将某种开发方法应用于项目时,您和您的管理层应始终使用常识。没有一种方法能够完美地解决所有问题/项目。你的工作的一部分是发现这种方法没有达到最佳效果的情况。。。如果必要的话,调整甚至放弃它。在这种情况下,您/您的项目使用TDD的方式让您发疯,这一事实清楚地表明有些地方不正确。

我认为人们忘记的一件事是,在自动化单元测试中,它仍然是一种编码实践。设置模板/泛型类、基类、助手类或您熟悉的任何其他常规软件开发模式来进行单元测试是完全可以接受的。如果你觉得自己在一次又一次地做同样的事情,那么你很可能是这样!这表明你的大脑在告诉你:“有更好的方法”