测试覆盖测试到底有什么用

Nodejs开源项目里怎么样写测试、CI和代码测试覆盖率 - CNode技术社区
积分: 13265
少抱怨,多思考,未来更美好
------------------------------------
StuQ明星讲师
Moajs作者
Node技术咨询
wx 是一个不错的微信应用框架,接口和网站做的也不错,和wechat-api是类似的项目
群里有人问哪个好
朴灵说:“不写测试的项目都不是好项目”
确实wx目前还没有测试,对于一个开源项目来说,没有测试和代码覆盖率是不完善的,而且从技术选型来说,大多是不敢选的。
那么Nodejs开源项目里怎么样写测试、CI和代码测试覆盖率呢?
目前主流的就bdd和tdd,自己查一下差异
mocha和tape
另外Jasmine也挺有名,angularjs用它,不过挺麻烦的,还有一个选择是qunit,最初是为jquery测试写的,在nodejs里用还是觉得怪怪的。
如果想简单可以tap,它和tape很像,下文会有详细说明
mocha是tj写的
var assert = require(&assert&)
describe('truth', function(){
it('should find the truth', function(){
assert.equal(1, 1);
断言风格,这里默认是assert,推荐使用chaijs这个模块,它提供3种风格
rspec里推荐用expect,其实看个人习惯
比较典型一个mocha例子
var assert = require('chai').
var expect = require('chai').
require('chai').should();
describe('Test', function(){
before(function() {
// runs before all tests in this block
after(function(){
// runs after all tests in this block
beforeEach(function(){
// runs before each test in this block
afterEach(function(){
// runs after each test in this block
describe('#test()', function(){
it('should return ok when test finished', function(done){
assert.equal('sang_test2', 'sang_test2');
var foo = 'bar';
expect(foo).to.equal('bar');
理解测试生命周期
理解bdd测试写法
单元测试需要的各个模块说明
mocha(Mocha is a feature-rich JavaScript test framework running on node.js and the browser, making asynchronous testing simple and fun.)
chai(Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.)
sinon(Standalone test spies, stubs and mocks for JavaScript.)
zombie (页面事件模拟Zombie.js is a lightweight framework for testing client-side JavaScript code in a simulated environment. No browser required.)
supertest(接口测试 Super-agent driven library for testing node.js HTTP servers using a fluent API)
如果你想真正的玩敏捷,从用户故事开始,那么下面这2个库非常必要
啊,黄瓜。。。。
tape:像代码一样跑测试
tape是substack写的测试框架
var test = require('tape').
test('equivalence', function(t) {
t.equal(1, 1, 'these two numbers are equal');
tape是非常简单的测试框架,核心价值观是”Tests are code”,所以你可以像代码一样跑测试,
node test/test.js
写个脚本就无比简单了。当然如果你想加’test runner’ 库也有现成的。
The Test Anything Protocol
它是可靠性测试的一种(tried & true)实现
从1987就有了,有很多语言都实现了。
它说白点就是用贼简单的方式来格式化测试结果,比如
TAP version 13
# equivalence
ok 1 these two numbers are equal
比如node里的实现/isaacs/node-tap
var tap = require('tap')
// you can test stuff just using the top level object.
// no suites or subtests required.
tap.equal(1, 1, 'check if numbers still work')
tap.notEqual(1, 2, '1 should not equal 2')
// also you can group things into sub-tests.
// Sub-tests will be run in sequential order always,
// so they're great for async things.
tap.test('first stuff', function (t) {
t.ok(true, 'true is ok')
t.similar({a: [1,2,3]}, {a: [1,2,3]})
// call t.end() when you're done
一定要区分tap和tape,不要弄混了
科普一下什么是CI
科普一下,CI = Continuous integration 持续集成
Martin Fowler对持续集成是这样定义的:
持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。
减少重复过程
任何时间、任何地点生成可部署的软件
增强项目的可见性
建立团队对开发产品的信心
1.统一的代码库
2.自动构建
3.自动测试
4.每个人每天都要向代码库主干提交代码
5.每次代码递交后都会在持续集成服务器上触发一次构建
6.保证快速构建
7.模拟生产环境的自动测试
8.每个人都可以很容易的获取最新可执行的应用程序
9.每个人都清楚正在发生的状况
10.自动化的部署
也就是说,测试不通过不能部署,只有提交到服务器上,就可以自动跑测试,测试通过后,就可以部署到服务器上了(注意是&staging&, 而非&production&)。
一般最常的ci软件是jenkins
举个大家熟悉的例子iojs开发中的持续集成就是用的jenkins
jenkins是自建环境下用的比较多,如果是开源项目,推荐travis-ci
对开源项目做持续集成是免费的(非开源的好贵),所以在github集成的基本是最多的。
对nodejs支持的也非常好。
近年随着tdd/bdd,开源项目,和敏捷开发的火热,程序员们不再满足说,我贡献了一个开源项目
要有高要求,我要加测试
要有更高要求,我要把每一个函数都测试到,让别人相信我的代码没有任何问题
上一小节讲的ci,实际上解决了反复测试的自动化问题。但是如何看我的程序里的每一个函数都测试了呢?
答案是测试覆盖率
在nodejs里,推荐
Istanbul - 官方介绍 a JS code coverage tool written in JS
它可以通过3种途径生成覆盖报告
$ npm install -g istanbul
$ istanbul cover my-test-script.js -- my test args
它会生成./coverage目录,这里面就是测试报告
比如我的项目里
./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly
#MongooseDao()
? should return ok when record create
? should return ok when record delete fixture-user
? should return ok when record deleteById
? should return ok when record removeById
? should return ok when record getById
? should return ok when record getAll
? should return ok when record all
? should return ok when record query
8 passing (50ms)
=============================================================================
Writing coverage object [/Users/sang/workspace/moa/mongoosedao/coverage/coverage.json]
Writing coverage reports at [/Users/sang/workspace/moa/mongoosedao/coverage]
=============================================================================
=============================== Coverage summary ===============================
Statements
: 47.27% ( 26/55 )
: 8.33% ( 1/12 )
: 60% ( 9/15 )
: 47.27% ( 26/55 )
================================================================================
默认,,如果你想生成html也可以的。
比如说,上面的结果47.27%是我测试覆盖的占比,即55个函数,我的测试里只覆盖了26个。
那么我需要有地方能够展示出来啊
我们以项目为例,介绍一下如何集成测试,ci和测试覆盖率
最终效果如图
package.json里定义自定义执行脚本
&scripts&: {
&start&: &npm publish .&,
&test&: &./node_modules/.bin/gulp&,
&mocha&: &./node_modules/.bin/mocha -u bdd&,
&cov&:&./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage&# | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage&
除了start和test外,都是自定义任务,其他都要加run命令
npm run mocha
npm run cov
gulp watch
var gulp = require('gulp');
var watch = require('gulp-watch');
var path = 'test/**/*.js';
gulp.task('watch', function() {
gulp.watch(['test/**/*.js', 'lib/*.js'], ['mocha']);
var mocha = require('gulp-mocha');
gulp.task('mocha', function () {
return gulp.src(path , {read: false})
// gulp-mocha needs filepaths so you can't have any plugins before it
.pipe(mocha({reporter: 'spec'}));
gulp.task('default',['mocha', 'watch']);
这样就可以执行gulp的时候,当文件变动,会自动触发mocha测试,简化每次都输入npm test这样的操作。
当然你可以玩更多的gulp,如果不熟悉,参考
创建.travis.yml
项目根目录下,和package.json平级
language: node_js
repo_token: COVERALLS.IO_TOKEN
services: mongodb
script: npm run mocha
after_script:
npm run cov
如果依赖mongo等数据库,一定要写services
把测试覆盖率放到执行测试之后,避免报402错误
在travis-ci.org上,github授权,添加repo都比较简单
添加之后,就可以看到,比如
travis-ci实际上根据github的代码变动进行自动持续构建,但是有的时候它不一定更新,或者说,你需要手动选一下:
点击# 10 passed,这样就可以强制它手动集成了。
其他都很简单,注意替换COVERALLS.IO_TOKEN即可。
创建 .coveralls.yml
nodejs下面的代码测试覆盖率,原理是通过生成测试数据,上传到coveralls网站上,然后以badge的形式展示出来
具体实践和travis-ci类似,用github账号登陆,然后添加repo,然后在项目根目录下,和package.json平级,增加.coveralls.yml
service_name: travis-pro
repo_token: 99UNur6O7ksBqiwgg1NG1sSFhmu78A0t7
在上,第一次添加repo,显示的是“SET UP COVERALLS”,里面有token,需要放到.coveralls.yml里,
如果成功提交了,就可以看到数据了
在readme.md里增加badge
[![Build Status](https://travis-ci.org/moajs/mongoosedao.png?branch=master)](https://travis-ci.org/moajs/mongoosedao)
[![Coverage Status](https://coveralls.io/repos/moajs/mongoosedao/badge.png)](https://coveralls.io/r/moajs/mongoosedao)
它就会显示如下
另外一种用Makefile的玩法实践
TESTS = test/*.js
REPORTER = spec
TIMEOUT = 20000
ISTANBUL = ./node_modules/.bin/istanbul
MOCHA = ./node_modules/mocha/bin/_mocha
COVERALLS = ./node_modules/coveralls/bin/coveralls.js
@NODE_ENV=test $(MOCHA) -R $(REPORTER) -t $(TIMEOUT) \
$(MOCHA_OPTS) \
@$(ISTANBUL) cover --report html $(MOCHA) -- -t $(TIMEOUT) -R spec $(TESTS)
test-coveralls:
@$(ISTANBUL) cover --report lcovonly $(MOCHA) -- -t $(TIMEOUT) -R spec $(TESTS)
@echo TRAVIS_JOB_ID $(TRAVIS_JOB_ID)
@cat ./coverage&# | $(COVERALLS) && rm -rf ./coverage
test-all: test test-coveralls
.PHONY: test
我个人更喜欢npm+gulp的写法,总是有一种make是c里古老的东东。。。
nodejs里常用框架
前沿技术:cucumber和vowsjs
科普一下CI
gulp + npm run
介绍了基于makefile的另一种玩法
欢迎关注我的公众号【node全栈】
好文,先马
来自炫酷的
好东西,顶起来~~~一直想看看自动化测试
怒顶啊,怒赞!
为什么没有收藏了捏捏捏,好晕,还要copy网址
终于知道 travis-ci.yml 是什么东东了。原来测试有好几步,我只写到mocha。
自豪地采用
唐少给隐藏了
基本上好点的开源项目都会有各种的配置文件~
一个网站 测试怎么写, 测试函数? API? 还是测试数据库orm?
cool, 最近正好想练练写测试 :)
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的测试覆盖 -
Testing coverage(覆盖),指测试覆盖被测试的程度,一项给定测试或一组测试对某个给定系统或构件的所有指定测试用例进行所达到的程度。
测试覆盖 -
万方数据学位论文
万方数据期刊论文
万方数据期刊论文
微电子学与计算机
为本词条添加和相关影像
互动百科的词条(含所附图片)系由网友上传,如果涉嫌侵权,请与客服联系,我们将按照法律之相关规定及时进行处理。未经许可,禁止商业网站等复制、抓取本站内容;合理使用者,请注明来源于。
登录后使用互动百科的服务,将会得到个性化的提示和帮助,还有机会和专业认证智愿者沟通。
您也可以使用以下网站账号登录:
此词条还可添加&
编辑次数:4次
参与编辑人数:4位
最近更新时间: 17:48:37
贡献光荣榜
扫描二维码用手机浏览词条
保存二维码可印刷到宣传品
扫描二维码用手机浏览词条
保存二维码可印刷到宣传品966,690 六月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
测试覆盖(率)到底有什么用?
测试覆盖(率)到底有什么用?
相关厂商内容
相关赞助商
APMCon中国应用性能管理大会,日-19日,北京新云南皇冠假日酒店,!
Brian Marick(敏捷宣言最早的17个签署人之一)也说过,作为一名程序员,我当然期望我的代码有较高的测试覆盖率。但是,当我的经理要求这样的指标时,那就有别的目的了(绩效考核?)。
我认为,高的测试覆盖率应该是每个“认真”写单元测试的程序员得到的必然结果,管理者把一个结果作为指标来衡量,本身就是没有意义的。如果你把“万能”的程序员逼急了,他就会从 “神秘的工具箱”中拿出一两个“法宝”来,“高效”地达成指标。我就见过很多这样的“法宝”,比如在单元测试中连一个“assert”也没有,或者写很多get和set方法的单元测试(写起来简单啊)来提高整体的覆盖率等等。更何况,测试充分的代码也有可能无法达到100%的覆盖率,本文的后面就有这样的例子。
那你大概会问:“那测试覆盖到底有什么用呢?”。我的答案还是很简单,“测试覆盖是一种学习手段”。学习什么呢?学习为什么有些代码没有被覆盖到,以及为什么有些代码变了测试却没有失败。理解“为什么”背后的原因,程序员就可以做相应的改善和提高,相比凭空想象单元测试的有效性和代码的好坏,这会更加有效。
接下来,我会给大家介绍一些传统的测试覆盖方法和一种称为“代码变异测试”(Mutation Test)的方法。大家将会看到这些方法都可以产生什么样的学习点,以及代码变异测试相比传统方法更有价值的地方。如果你是一名程序员(我不会区分你是开发人员还是测试人员,那对我来说都一样),希望你看完这篇文章之后,可以找到一些提高测试和代码质量的方法。如果你是一位管理者,不论你正在用还是想要用“测试覆盖率”来做度量,希望你看完这篇文章之后,可以放弃这个想法,做点更有意义的事情(比如去写点代码)。
传统的测试覆盖方法
传统的测试覆盖方法常见的有以下几种:
函数覆盖(Function Coverage)
语句覆盖(Statement Coverage)
决策覆盖(Decision Coverage)
条件覆盖(Condition Coverage)
还有一些其他覆盖方法,如Modified Condition/Decision Coverage,就不在这里讨论了。
函数覆盖:顾名思义,就是指这个函数是否被测试代码调用了。以下面的代码为例,对函数foo要做到覆盖,只要一个测试——如assertEquals(2, foo(2, 2))——就可以了。如果连函数覆盖都达不到,那应该想想这个函数是否真的需要了。如果需要的话,那又为什么写不了一个测试呢?
语句覆盖:(也称行覆盖),指的是某一行代码是否被测试覆盖了。同样的代码要达到语句覆盖也只需要一个测试就够了,如assertEquals(2, foo(2, 2))。但是,如果把测试换成assertEquals(0, foo(2, -1)),那就无法达到所有行覆盖的效果了。通常这种情况是由于一些分支语句导致的,因为相应的问题就是“那行代码(以及它所对应的分支)需要吗?”,或者“用什么测试可以覆盖那行代码所代表的分支呢?”。
决策覆盖:指的是某一个逻辑分支是否被测试覆盖了。如我上面所说,语句覆盖通常和决策覆盖有关系。还是以上面的代码为例,要达到所有的决策覆盖(即那个if语句为真和假的情况至少出现一次),我们需要至少两个测试,如assertEquals(2, foo(2, 2))和assertEquals(0, foo(-1, 2))。如果有一个逻辑分支没有被覆盖(比如只有测试assertEquals(2, foo(2, 2))),那么我们应该问和上面“语句覆盖”小节中相似的问题。
条件覆盖:指的是分支中的每个条件(即与,或,非逻辑运算中的每一个条件判断)是否被测试覆盖了。之前的代码要达到全部的条件覆盖(也就是x&0和y&0这两个条件为真和假的情况均至少出现一次)需要更多的测试,如assertEquals(2, foo(2, 2)),assertEquals(2, foo(2, -1))和assertEquals(2, foo(-1, -1))。如果有一个条件分支没有被覆盖(比如缺少测试assertEquals(2, foo(-1, -1))),那么大家应该想想“那个条件判断是否还需要呢?”,或者“用什么测试可以覆盖那个条件所对应的逻辑呢?”。
通过上面对几种传统的测试覆盖方法的介绍,大家不难发现,这些方法的确可以帮我们找到一些显而易见的代码冗余或者测试遗漏的问题。不过,实践证明,这些传统的方法只能产生非常有限的“学习”代码和测试中问题的机会。很多代码和测试的问题即使在达到100%覆盖的情况下也无法发现。然而,我接下来要介绍的“代码变异测试”这种方法则,它可以很好的弥补传统方法的缺点,产生更加有效的“学习”机会。
代码变异测试(Mutation Test)
代码变异测试是通过对代码产生“变异”来帮助我们学习的。“变异”指的是修改一处代码来改变代码行为(当然保证语法的合理性)。简单来说,代码变异测试先试着对代码产生这样的变异,然后运行单元测试,并检查是否有任何测试因为这个代码变异而失败。如果有测试失败,那么说明这个变异被“消灭”了,这是我们期望看到的结果。如果没有测试失败,则说明这个变异“存活”了下来,这种情况下我们就需要去研究一下“为什么”了。
是不是感觉有点绕呢?让我们换个角度来说明一下,可能就容易理解了。测试驱动开发相信大家一定都听说过,它的一个重要观点是,我们应该以最简单的代码来通过测试(刚好够,Just Enough)。基于这个前提,那么几乎所有的代码修改(即“变异”)都应该会改变代码的行为,从而导致测试失败。这样的话,如果有个变异没有导致测试失败,那要么是代码有冗余,要么就是测试不足以发现这个变异。
另一方面,大家可以想一下对于自动化测试(包括单元测试)的期望是什么。我觉得一个很重要的期望就是,自动化测试可以防止“任何”错误的代码修改,以减少代码维护带来的风险。错误的代码修改实际上就是一个代码变异,代码变异测试可以帮我们找到一些无法被当前测试所防止的潜在错误。
举例来说,我们给之前的那段被测代码增加一行,sideEffect(z)。之前的那些可以让传统的测试覆盖方法达到100%覆盖率的测试,在新增这行代码之后,依然会全部通过且覆盖率不变。然而,如果我们再删除那行新代码sideEffect(z),结果有会怎样呢?那些测试还是会全部通过,覆盖率也还是100%。在这种情况下,原来那些测试可以说没有任何意义。相对的,代码变异测试则可以通过删除那一行,再运行测试,就会发现没有任何测试失败。然后,我们就可以根据这个结果想到其实还需要一个测试来验证sideEffect(z)这个行为(如果那行代码不是多余的话)。
再举一个例子,还是之前的代码,不做任何修改。我们用assertEquals(2, foo(2, 2)),assertEquals(2, foo(2, -1))和assertEquals(2, foo(-1, -1))这三个测试达到了100%的条件覆盖。然而,如果把y & 0的条件改成 y &= 0的话,这三个测试依然会通过。为什么会出现这样的问题呢?那是因为之前的测试对输入参数的选择比较随意,所以让这个代码变异存活了下来。可以看到,在条件覆盖100%的情况下,代码变异测试依然可以帮我们发现这种测试写的不严谨的问题(假设y &= 0这个代码变异是不合理的),从而使修改后的测试可以防止产生这样的错误代码。
通过上面两个例子,相信大家已经发现代码变异测试可以给我们提供大量的学习代码合理性和测试有效性的机会。实际上,类似的代码变异还有很多种。下面是常见变异的列表,更详细的内容可以参考 http://pitest.org/quickstart/mutators/ 。
条件边界变异(Conditionals Boundary Mutator)
对关系运算(&, &=, &, &=)进行变异,上面第二例子就是这种变异
反向条件变异(Negate Conditionals Mutator)
对关系运算(==, !=, &, &=, &, &=)进行变异,例如把“==”变成“!=”
数学运算变异(Math Mutator)
对数学运算(+, -, *, /, %, &, |, ^, &&, &&, &&&)进行变异,例如把“+”变成“-”
增量运算变异(Increments Mutator)
对递增或者递减的运算(++, --)进行变异,例如把“++”变成“--”
负值翻转变异(Invert Negatives Mutator)
对负数表示的变量进行变异,例如把“return -i”变成“return i”
内联常量变异(Inline Constant Mutator)
对代码中用到的常量数字进行变异,例如把“int i=42”变成“int i=43”
返回值变异(Return Values Mutator)
对代码中的返回值进行变异,例如把“return 0”变成“return 1”或者把“return new Object();”变成“new Object();”
无返回值方法调用变异(Void Method Calls Mutator)
对代码中的无返回值方法调用进行变异,也就是把那个方法调用删除掉,上面的第一个例子就是这种变异。
有返回值方法调用变异(Non Void Method Calls Mutator)
对代码中的有返回值函数调用进行变异,也就是接收返回值的变量赋值将被替换成为返回值类型的语言默认值,例如把“int i = getSomeIntValue()”变成“int i = 0”
构造函数调用变异(Constructor Calls Mutator)
对代码中的构造函数调用进行变异,例如把“Object o = new Object()”变成“Object o == null”
测试驱动开发和代码变异测试
测试驱动开发(TDD)是我推崇和实践的写代码(做设计)方法。我在前面曾经提到,代码变异测试的假设是“实现代码是刚好够通过测试的最简单代码”,而这也是TDD中的重要实践之一。大家可能会问,如果做了TDD,代码变异测试的结果又会如何呢?还会产生学习的机会吗?答案是肯定的,一定会。
让我们通过例子来看一下。我经常会做一些Kata来练习编程技巧,PokerHands(如上图)就是其中之一(其实大体就是实现梭哈的五张比较规则)。每次我把Kata做完之后,都会用运行一下代码变异测试(sonar中有插件)。Java的代码变异测试工具有个比较好的叫pitest。下面是我用这个工具跑出来的结果,代码可以在这里找到。
如大家所见,红色那一行中有一个存活下来的代码变异。而这个代码变异是把“index & CARD_COUNT - 1”中的“&”换成“&”。看上去很不可思议吧,因为进行这样的代码变异意味着整个for循环都不会被执行了,应该不可能没有一个测试失败吧?
让我们来看一下相关的单元测试。在下面这个测试中有三个assert,它们都是在验证“一对”之间通过对子的点数来比较大小的情况。大家仔细观察就可以发现,其实这三个assert中的牌如果作为High Card(就是比一对小一点的牌组)来比较的话,也都是成立的。这也就是那个代码变异可以存活下来的原因,因为即使忽略了一对之间的比较,通过High Card比较出来的大小关系也是一样的。我从中学到的是,只要把 assertPokerHandsLargerThan("2S 3H 5S 8C 8D", "2S 3H 5S 7C 7D") 改为 assertPokerHandsLargerThan("2S 3H 5S 8C 8D", "2S 3H 9S 7C 7D")就可以清除这个代码变异了。
从这个例子中可以看到,即使以TDD的方法来写代码,也是无法完全避免出现代码变异存活下来的情况的(当然,存活变异的数量要非常明显的少于不用TDD而写出来的代码)。做过TDD的人可能都有这样的感觉,就是有时很难抑制自己写出复杂代码的冲动(也就是说代码不是“刚好够”的)。有时,即使实现代码是最简单的,也可能因为代码过于直接,就会很“随意”的写出一个让当前代码失败的测试。上面的例子就是这种情况,这样不太“有效”的测试通常在TDD过程中很难意识到,从而给之后的代码维护造成隐患。
除了上面那个有学习意义的代码变异之外,其实工具还帮我找到了一个“没意义”但存活下来的代码变异。
这里存活下来的代码变异是指把“index & CARD_COUNT - 2”中的“&”变成“&=”。之所以说这个代码变异没意义,是因为根据代码上下文,在for循环中一定会在index等于CARD_COUNT - 2之前就找到那个三张的点数。因为工具无法理解上下文,所以产生了这个没意义的代码变异(也叫做Equivalent Mutation)。之所以举这个例子,只是想提醒大家不要迷信代码变异测试工具。对于他产生的结果一定去分析和学习,不然很容易走上考核指标的那条不归路。
总而言之,测试覆盖这种方法是一种不错的学习手段,可以帮助我们提高代码和测试质量。代码变异测试则比传统的测试覆盖方法可以更加有效的发现代码和测试中潜在的问题,提供更多的学习机会。在这里,我要郑重警告那些妄图把代码变异测试变成一种新的考核指标的管理者们,这样做只会迫使程序员从他的神秘工具箱中找出新的法宝来对付你(比如,修改编译器等等)。
代码变异测试的概念其实早在30年前就被提出了。之所以到目前为止还没有被业界广泛接纳,一个重要原因是由于需要对每个代码变异反复运行测试。如果不是单元测试(运行速度慢),代码变异测试工具执行时将消耗大量的时间。正因如此,单元测试可能是唯一符合代码变异测试要求的一种测试了。如果你对代码变异测试的历史和发展过程感兴趣的话,你可以参考这篇研究报告
关于姚若舟
姚若舟是Odd-e的一名敏捷教练,为团队提供敏捷实践的教导和培训。他在软件业有超过十三年的开发和项目管理经验,熟悉互联网,移动和桌面软件的开发。他是中国敏捷社区的积极参与者和组织者。作为一名追求软件工艺的程序员,他从2011年开始坚持每天通过Coding Kata来不断提高自己的编程技巧。同时,他还在不少公司,社区沙龙和会议中组织过许多次代码道场(Coding Dojo)和Coderetreat的活动。
他有非常丰富的Scrum经验,曾长期担任ScrumMaster,服务于多个开发团队和Product Owner。他擅于在各种Scrum会议和日常工作中通过提问来引导和帮助团队成员发现潜在的问题和改善机会,从而真正实现团队的敏捷转型。
他对软件工艺的各类实践(如编写高可读性代码,单元测试,重构,遗留代码隔离,测试驱动开发(TDD)等)有着深入的了解和丰富的实战经验。同时擅于通过Coding Dojo这种编程练习的方式来帮助开发人员提高编程能力和代码质量。他精通Java语言,熟悉基于Java的Web开发中的常用协议,开源软件和工具。
感谢对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至。也欢迎大家通过新浪微博()或者腾讯微博()关注我们,并与我们的编辑和其他读者朋友交流。
Author Contacted
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
InfoQ每周精要
通过个性化定制的新闻邮件、RSS Feeds和InfoQ业界邮件通知,保持您对感兴趣的社区内容的时刻关注。
架构 & 设计
文化 & 方法
<及所有内容,版权所有 &#169;
C4Media Inc.
服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?

我要回帖

更多关于 语句覆盖测试用例 的文章

 

随机推荐