新闻资讯

新闻资讯 媒体报道

时间管理和知识管理

编辑:011     时间:2022-01-21

很高兴能够在coding技术小馆做一场演讲。我是coding的资深用户,从两年前到现在一直都在使用coding的各种产品,包括但是不限于抱枕,毛巾和餐具。当然,顺便也多少用过一点代码托管这种周边业务。


这张图不是我的,是我学生的,真的是特别的拼,每次打开他的主页我都觉得压力很大。


简单自我介绍一下,我毕业之后在浏览器公司做过很长时间的前端,也做过一段时间的自由程序员,后来在掘金写了几个月的nodejs,现在是一个前端讲师。对,我是个培训班的讲师,你们懂的。

所以当过过问我要不要来做技术分享的时候,我问她,你不担心我过来讲成功学吗?她说,你的技术应该挺好的吧?我说,难道你忘了我们其实是在相亲群里认识的么?

然后我就列了好几个题目给她,她说好像看起来都不错,组织上还是很信任你的,你随便挑一个题目就行。你知道,随便是一个特别难搞的需求,于是我陷入了深深的思考。从毕业到现在也参加过几十场大大小小的线下活动,主持过几百人规模的技术分享,也做过企业内训以及日常上课。对于这个规模的沙龙来说,什么样的题目和演讲角度以及方式比较合适,我也曾经做过很多设想。

这次技术小馆其实是我第一次在技术圈做线下的分享,所以呢也想做个试验,我保证你们从前不会听过这样的分享,但是我也不知道这样子到底好不好,大不了就请过过吃个饭好啦。

这次分享选了这么个奇怪的题目,叫《从AVA到TDT》,本质上来说,今天要讲的是工程化的事情。到底是怎么回事,我会用后面三十多分钟的时间来给你们解释。

现在进入正题:

什么是测试?

首先我想问一下,在场有哪些朋友曾经写过前端测试?看起来并不是很多。没关系,我们今天就一起来了解一下测试。

这是测试中的一个经典模型,叫做V模型。

我们计算机专业课中,都有软件测试这门课,讲的应该就是这个模型,我们可以发现V模型的几个特点:

首先,测试是开发之后的一个阶段。

这就意味着,可能在系统设计阶段发生的错误,直到系统测试阶段才被发现。这件事情大家想想看,其实很常见对吧, 俗称:产品经理改需求。

另外就是这种单线程的开发方式,如果有一个环节delay,那么整个工程的进度都会受到影响,或者只能压缩测试的时间,这些事情都是可以预见到很有可能发生的。

互联网产品测试

互联网产品的测试和传统的软件测试有什么不同?

写代码不能像做菜,把所有的功能都做好了才上线

曾经和做iOS开发的朋友聊天,他说他们都不加班,反正半夜苹果也不会给你审核。但是我们web就不一样,24小时,什么时候网站挂了,什么时候就要hotfix。

一些大厂网站可以做到每天多次甚至十多次上线,这个开发流程已经不能用V模型来表达了。各个测试环节无论从顺序还有比重上都要做出调整。

TDD和BDD

Test Drive Development 即“测试驱动开发”,是一种听起来很厉害,但是大家都不怎么用的方法。刨除项目排期紧张这个因素之外,非模块化的代码也很难用TDD的方式组织测试。

好消息是随着现代前端越来越多的应用模块化和组件化,TDD的方式更容易被实践,细粒度的模块意味着可以更好的去做单元测试,这不仅更容易设计测试用例,也能够很好地保证测试覆盖率。我们可以纯粹用TDD的方式来设计模块,交给年轻一点的同事去做,既降低了开发难度,又能够保证模块质量。

当需要加入业务逻辑组合使用模块的时候,我们就要运用BDD(Behavior Drive Development),行为驱动开发的方式,用自然语言来描述各种行为去做测试。

TDD像是设计文档的代码表示,用来限定工程师的代码是否符合了最初的规划。而BDD则类似用户的真实行为,我们可以在其中设计很多边缘条件的测试,以及多模块协同作业的测试。

## 前端测试

这里可能要对“前端”这个词做一点解释。狭义的前端指的是网页开发者,而现在我们在很多语境中提到的前端其实指的是“使用JS语言的开发者”。

我在日常使用测试的场景可能和你们大家都不一样,因为我是做培训的,测试对于我来说,主要是用来做OJ系统。所以主要的关注点是在模块和业务逻辑上,而UI测试的内容我完全没有涉猎,今天也不会提及。

karma+mocha+chai 是一套经典的前端测试组合。

其中karma是启动器,mocha也是TJ大神的作品,是一个测试框架,chai是一个断言库。

我们稍微解释一下什么是断言库。断言是一些布尔表达式,我们常见的断言也分为TDD风格和BDD风格

// with an assert style


   assert.equal(event.detail.item, '(item).);





   // or an expect style


   expect(event.detail.item).to.equal('(item)');





   // or should style


   event.detail.item.should.equal('(item)');

## AVA


AVA给自己做的定义是:面向未来的测试运行器。

从这个名字我们可以看到,它自己就是一个运行器,同时也是测试框架,顺带自己又实现了断言库。

和mocha相比,它对es6的语法支持情况更好,支持aysnc/await,Generator,Observable各种异步的方式,同时也很好的支持了回调函数。

第二点是,AVA是并发测试的,所以一定要做原子类,一方面是从框架设计的角度就规范了TDD的实践,另一方面,并发测试也大大提高了测试的速度。

AVA的语法很简单直观

import test from 'ava'





test('my test', t => {


  t.is(3, 3)


})

自带断言:

true,false

is,not

deepEqual,notDeepEqual

regex,notRegex

支持串行

test.serial(t => {


    t.pass();


});

强化断言信息:

注意

并行测试同时操作同一个临时文件会带来意想不到的结果。所以我们可能要为每个测试准备不同的临时文件,比较典型的空间换时间策略。

另一个问题是并发测试不能保证输出顺序,所以在有些时候可能还要去指定串行的方式。


怎么来做一个OJ

首先我们先跑一下AVA的DEMO,这个还是比较容易的,很快就搞定了。然后问题来了,我们怎么用js来调用AVA呢?

首先想到了可以用exec方法。老规矩,先跑一个最简单的exec的DEMO,跑通了,但是和ava结合的时候完全不行。推测是因为AVA自己本来就是多进程的,所以这条路搞不定。

我就突然想到,mocha能不能做?是什么路子?

于是去查了一下mocha提供了给nodejs的API,但是AVA是没有的。继续找AVA的周边项目,按照node社区的一贯风格,八成是有个[awesome-ava](avajs/awesome-ava)项目的,结果真的有。

发现了一个叫做start-ava的项目,是利用start来运行AVA,所以一个新的问题就是:start是啥?

这个故事又告诉了我们一个道理:不要给自己的类库起这种SB的名字,不然真是除了github以外,满世界都找不到能参考的资料。

然后我们尝试了一下start的DEMO,好像也比较容易成功,但是start-ava这个插件依然不支持直接返回String,而是在参数中可以设置一个tapSepec,作为tap的格式化的工具函数。

打开tap-spec之后发现这个输入输出是基于stream的,以前只有做文件上传的时候接触过,并没有详细看过原理,就只能看一遍steam的示例讲解,好在这方面的资料远比AVA的要多。


所以说到这里,你们应该察觉到了一件事:我其实并不会用AVA。


所以这次演讲到底要讲什么?

别着急,记得题目叫做什么吗?《从AVA到TDT》,TDT是什么?应该没有人知道,因为这是我造的一个词。我在想到这个点子的时候,还蛮激动的和同事说,我想到了一个新的理论,叫做“测试驱动教学”(Test Drive Teaching)。

同事看了我一眼,说,你这是毛线的新理论,不就是应试教育么?


时间回到一周前

一周前过过来找我的时候,我正在设计给学生的项目实践,也收集了有关前端工程化的方方面面。比如代码版本管理,模块化,组件化,自动化构建,基于看板的敏捷开发流程等。但是对于时间管理和知识管理这两个非常重要,但是我们往往没有纳入到工程化中的内容,怎么去把控?

我用自己做了这一周的试验。


一分钟可以做什么

先推荐一个软件,ManicTime可以记录你每天操作电脑的所有细节。当你翻看每天记录的时候你就会发现从前对于自己是多么的不诚实。

一次文档查找,或者一个简单的api修改,这些事情在我们自己的感知中,应该就是一瞬间的事情,但是这个一瞬间可能就要花费一分钟时间。

对于技术含量比较低的事情我们往往估计的过于乐观,只有一种短时任务可以精确估计时间,那就是你背着都能写下来的代码,比如实现一个冒泡排序,这就完全取决于打键盘的速度了。而打键盘的速度也因为习惯而天差地别。

比如是使用快捷键删除整行代码,还是连续按退格键删除,两者会相差成倍的时间。

使用snippet带来的巨大的效率提升就更加明显了。像ejs这种使用jsp分隔的模板,%本身就是一个非常低效的输入内容。

另外一旦需要去查找资料,时间会变得非常不可控。


一天可以写多久代码

按照朝九晚六来算,每天可以有八小时的工作时间,有一半的时间在写代码还是比较合理的,对么?

这是我这个月最勤奋的一天,也是确定演讲题目的那天。

可以看到那天电脑的活动时间将近17个小时,而在编辑器中的时间是4个小时。事实上比较日常的比例也是八小时的工作时间,对应2小时的编码时间。连续编码时间一般在4分钟以内,然后就需要切出去看效果或者查阅资料。

这个结论可能也很出乎意料,我们频繁的从编辑器切出到浏览器或者控制台,以及查阅资料或者去聊天,这些事情才是占据日常大部分时间的。


什么时间最高效

程序员往往表示,晚上是最高效的,一般是后半夜更高效一点。我在查看了自己的时间线之后发现其中的奥秘在于,后半夜的时候你因为社交(微信消息)和社区(刷微博,刷知乎)而打断的次数明显减少了,这个效果确实非常明显。


避免过度优化

技术人员另外一个容易进入的误区就是唯技术论。因为AVA是看起来更优秀的测试框架,所以我就要去选择它么?但是首先它的文档情况不好,配套的类库也不够好用。其次,我的需求也并不要求强制做并行测试,mocha是可以符合要求的。再退一步说,我只用原生的断言也可以做到。我们以BDD的眼光来看,这个时间成本是可以由planB来保障的。

有学生问过我,引入第三方样式类库之后,自己原来写的样式被覆盖无法生效,怎么处理。我说直接在body上加个id,然后恁在选择器里。

多一层选择器是不是会影响性能?当然会,但是我们的场景还没到谈性能的时候,一个牺牲一点性能换取高效解决问题的方法,不正是工程化的理念么。


deadline为什么高效

我们在上大学的时候就体会过,deadline有着神奇的力量,极大地推动着我们前进,但是deadline为什么可以这么大幅提高效率?

因为学习或者是编写新功能的时候,比起技术上的阻力,可能脱离舒适区的阻力会更大一些。而deadline直接砸碎了你的舒适区,你无处可躲,只能咬呀往前走。

所以这次演讲某种程度上也是在破坏舒适区,我为了顾及面子,不得不在一周内收集足够的和测试相关的资料,并整理出来,以及有一定的实践和理解以应付听众提问。


TDT

把自己的知识作为一个产品,学习过程就相当于开发。我们尝试套用TDD和BDD的思想来进行学习。

TDD的学习模式是:预设测试,通过完成测试来学习。

比如:this有几种情况?非有几个取值?变量有多少种方式进入函数内部?当你掌握了这些答案的数字,就意味着把握了整体的知识,是一个严丝合缝的知识结构。我把这些数字称为“100分的答案”,因为这些答案是完全正确而且全面的,完美和差不多之间有着量变和质变的区别,就像是覆盖率100%和90%的项目的区别。

push函数需要几个参数?任意个,返回值呢?传入内容之后新数组的长度。

记住这些事情其实就是对知识点做边缘测试,而边缘测试也是我们保障代码质量的重要测试内容。

你会发现很多时候我们并不难写出一份100%覆盖的测试文档,毕竟HTML有几个标签,甚至jQuery有几个方法,都是白纸黑字写好的,你只要去查阅文档,然后设计一套测试,再努力的去完成这份测试就好。

有一点要注意的,就是在设计测试的时候,不要想完成起来是不是很麻烦,毕竟这是在给自己挖坑。要想象着是给别人出题,可能对于我们双子座来说,比较容易做到的。

我有一些你们没有的优势,就是每天我都要几个小时的被人盯着屏幕看,而且可能没发拒绝那些看起来很麻烦的事情,比如写一个可以高亮的滚动歌词,如果只有我一个人,我肯定会觉得麻烦,但是大家都看着我,我就只好表示很简单,然后从.lrc文件开始把歌词格式化,再和歌曲进度联动,用一个简单的算法让歌词比较自然的滚动起来。

这种方式其实就是BDD了,以行为驱动学习。


我们再来看这个图。在我提出“打算做一个OJ”之后,我依次学习了AVA,exec,mocha API,start以及stream。这件事对于我来说并不是负担,恰恰相反,这是一个非常好的学习过程。这种很多年轻的前端同学头疼的事情,其实是很好的成长途径。

这是一个大蒜,相信很多不太会做饭的朋友也知道大蒜如何使用,或者可以判断出在哪些菜里面用大蒜是合适的。

这是欧芹,应该很少有人能够想出欧芹可以搭配的菜肴。

因为虽然很多人都见过欧芹,但“欧芹”这个知识点和我们已有的知识点几乎没有关联,哪怕曾经用过,却无法运用。

而“大蒜”和我们生活中茫茫多的食材都发生过交集,所以我们可以说熟悉它,或者掌握了它。这个理论不是烹饪书上说的,你可以在普通心理学的课本里面找到。

总而言之TDD的学习方式帮助提高我们的知识覆盖率,而BDD的方法强化内容之间的关联,通过已知知识延伸到未知。


线下沙龙的意义

如果人数比较少,大家针对一个具体问题,比如服务器渲染做深入的讨论,必要的时候直接掏出笔记本来写代码,这是一个很理想的场景。

如果是我们这种单项数据流的技术分享(当然你们偶尔可以emit一个问题给我),一个优秀的架构应该是我传递一些status到子组件,然后子组件根据这些status再去调用方法解析。所以大家可能会收获一些关键词,这是有价值的。

另外一点,在面对面的交流中,能够被引导做出一些平日少有的思考,也是很大的收获。

最后一点就是面基这种形式可以交朋友,有人认识了好朋友,有人还找到了男朋友。

你看我在写这段话的时候,也是用了TDD,预设了四种情况,再依次把每种情况解释清楚。


结尾

从已经成熟的领域提取模型,借鉴思想,可以帮助我们少走很多弯路。测试是一件严肃而重要的事情,我相信未来的互联网公司对于测试会有越来越多的需求。无论是对于职业发展,还是帮助个人成长,去了解测试都是很有好处的。你们可以很有信心,因为你们面前的这个人花了一周时间就可以来给别人讲测试的理论,其实在你们看不见的地方,他也写了很多代码,没办法,做程序员不写代码是不行的。

这场演讲还告诉了我们一个重要的道理:不要随便去用你不熟悉的类库!没有因为mocha遇到瓶颈的话,千万别轻易用AVA,如果时间能倒退,我肯定要改题目的,你们去查一下这个东西有多少中文文档以及有多少英文文档,就知道是多么坑了。

这次演讲也当做一个产品来说,最好的方式就是从开发初期就指定严格的文档,所以其实一开始就计划好了要说的每一句话。当然,也包括这一句。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐