00:00
大家可以看到我这个也是跟着前前两次我们讲的这个编译脚本和部署脚本一样啊,然后我们也可以看到,就是整个这个流程,就是我们所说的真正的开发产品从开发到测试整个完善的一个流程,那当然我们这一次所说的这个测试呢,并不是真正意义上的就是大家所认为的那种产品测试,呃,就是包括什么?呃,这个所所谓的什么回归测试啊,对吧,就是各种各样的这种这种检测,不是那种专业的测试去做的东西,那我们这一部分其实就是开发人员日常所说所做的单元测试了,大家平常如果之前有过开发经验的话,肯定也知道我们自己开发完一段代码之后,如果不测就直接提交。呃,这个如果要能这样写出来程序还一点问题没有的话,要不就是本身我们自己的代码水平很高,要不就是这个可能逻辑特别简单,那大家如果写一个hello word,那应该不会有什么问题,对吧?提交上去之后任何问题都不会有,但是如果我们平常是稍微复杂一些的逻辑的话,就算我们之前用remix去开发简单合约,大家都会发现你直接写完之后可能也会有各种各样的错误,所以其实单元测试这个环节对于我们开发人员来讲也是必不可少的一步,那我们今天就是专门把这个拿出来,也给大家完整的去做一个介绍,呃,因为这个为什么要讲这个测试脚本呢?其实大家也就会发现,我们在之前呢,我们其实是有测试这一步的。
01:44
只不过我们可能没意识,对吧,我们之前是怎么做的测试呢?我们编写合约的时候写用solidity写完,写完合约,然后我们直接把它复制到remix里面,或者直接在remix里面编辑完了之后,我们就发现在remix上直接可以部署,部署完了之后我们就会发现下面生成了相关的方法的那个按钮,对吧?我们就可以给他写几个参数,然后点一下看看效果,那其实这个就是一个简单的测试。
02:13
呃,当然大家会发现这个东西很糙,而且没有办法流程化,那除了这一个呢,我们在之前在做这个最简单的投票合约的这么一个相当于D的一个小项目的时候,我们当时做过一些单的控制台的交互,我们启动一个GA,或者是启动一个gash,大家直接进入到note控制台里边,或者gas控制台里边,然后去敲一些命令,这个就可以检测我们输什么样的命令,它应该有什么样的返回给我们,那这其实也是一个简单的测试的过程,但是同样就是这个过程呢,我们也是很随意的,我们可能就是想到什么就敲什么,想到什么就写什么,呃,这个过程其实是没有办法标准化的。
03:00
另外当然也就大家发现我们每次去启动控制台之后,就会发现每一次啊,如果在gas里边可能还好,在node控制台里面,那更是一上来之后先要WEB3,等于require web3对吧,然后在new一个WEB3把它的那个点pro providers加进去之后,我们还要部署合约对吧,创建合约实例,然后就是各种各样复杂的情况,比如说我们还得呃去读取这个字节码啊,Abi这些东西,那之前我们做这个编译和部署脚本的,其实就是要把我们这些繁琐的工作自动化,一开始大家不熟的时候,我们一步一步去做是非常有有必要的,熟了之后,那我们用一个脚本去完成这些操作,其实就会舒服很多,所以我们也就想到,那既然编译和部署。能够脚本化,那同样我们的测试也能够脚本化,自动化,所以呃,那大家就会想到,我们如果要想把这个测试脚本化。
04:04
的话,我们就是直接写这个note JS的脚本吧,有没有一些现程可用的框架,好用的工具呢?那我们这里就给大家介绍一个这样的测试框架,也就是说所谓的mota mota呢,它主要是一个JS的一个测试框架,有没有同学以前用过,我上次问好像是大家都没怎么听说过是吧?呃,它应该是在现在就是作为一个前端的测试框架,或者说后端如果用node来写的话,作为这个JS的测试就是用的是很广泛,也是很普遍的一个一个工具啊,所以我们在这里就跟大家都都讲一下吧,尽管可能本身moa跟区块链关系不大,但是我们既然能够涉及到的工具嘛,大家是学区块链,就会发现区块链就是一个大综合,所有的东西都会融合在里面,所以大家就尽管之前可能没没有接触过,我想我们也不应该排斥或者。
05:04
我也不应该觉得,哇,这个东西我没用过,那还要还要另外学一个东西,好好麻烦好难啊。呃,其实不会,大家用一下的话就会发现,其实很多东西很简单,大家只要底层的东西知道这些东西没有没有任何难度啊,好,那么首先我们就安装依赖了,呃,就是这个就没什么好说的,既然我们要用Mo嘛,所以说首先就是n PM in store Mo产,那就这么一句简单的命令,我这里后面带了杠杠CD的一个参数,呃,那大家可能已经知道就是它是有什么作用的是吧,就我们安装的这个Mo叉安保存到我们本地的开发环境依赖里面去,好,我们打开这个bash来操作一下啊。呃,我现在先list一下,我现在应该是已经装过了。好,我到另外一个我们这个合约工作流的环境里边来,大家看一下这个里边,好,这里边什么东西都没有啊,好,我们在这个比较比较这个空的这个环境里边给大家演示一下,之前大家应该已经建了这个contract work flow这个文件夹,就是保存我们的工作流,那我们之前是已经有编译脚本和部署脚本都放在里边了,那同样这一次我们的测试也是接下来工作流了一部分,所以放在里边就可以n PM in store啊,直接那个Mo场,大家如果愿意的话,可以加上这个参数,看看我们的网络怎么样。
06:51
好,看起来够呛啊,我我那就还是不要跟大家就是抢占带宽资源了,那么大家肯定知道怎么样去保存这个对吧,那我这里要跟大家说的是,大家可以看一下这个package Jason。
07:04
这个里边其实它是保存了,如果大家之前做过n PM in的初始化的话,那我们就目录下面默认有一个pack package Json,它里边存的是什么内容呢?初始化之后首先存的是我们这个NPM包管理,整个是一个项目,就把它当成一个项目来管理,存的是我们这个项目的一些原数据,一些基本信息,那大家可以看到有name version啊什么的,那如果我们刚才执行了in n PM install Mo,刚杠CD之后,它是一个什么效果呢?我给大家看一下,在我这个下面应该能看到已经装过的效果啊。大家可以看到这里边就会多一个dev dependences,大家可以看到这个啊,所以下边大家可以看到我这里有两个dependency,也就是依赖,依赖的包,依赖什么呢?Gash和Mo产,所以这就是我当时装gash的时候也是写了一个杠杠save d,呃,然后Mo产的时候也是杠杠save d这样装上的,大家可以发现就是它会写到这个patri Jason里边。
08:15
诶,有些同学可能见过,有些教程里边,它后面会跟一个杠杠save对吧?这个会写写到哪里呢?会写到上面的这个dependency里边,那对于NPM它的管理来说就是dependency里边的依赖是我们整个打包发布,就是做产品发布的时候需要去打包在一起的内容,那DV dependenceency呢,那是开发环境的依赖,所以说它真正打包产品的时候就不会打包进去,我们打包出来的项目就会小一点,安装包就会小一点,啊这是这一部分啊,啊,大家应该都已经装完了对吧?好,那么接下来我们来说就是除了这个moa之外还要安装什么,就是还要安装gash GA纳SH,应该大家之前装过了,对吧?呃,这里呢,大家注意,我们之前在做部署的时候,编译用不到部署的时候,大家一般都是直接进到。
09:16
Node modules下边有一个点并对吧,然后会有这个跟纳在直接在这里边启动。就可以起一个我们就是本地的内存里面模拟的区块链节点,对吧,以太坊节点,那大家是不是都是这么启动的,对吧?现在呢,我们是做测试,那测试的情况我们只要安装了依赖包就可以不用这种方式,每次都启动了,那等一下到底怎么样去做呢?我们到时候再大家只要安装了依赖,到时候我们再去看好那么呃,这里要说的就是我们这里用的WEB3,还是上次就是安装的这个1.0.0的版本啊,因为我们上次已经装了,所以说就不换了,那大家如果要是想要用0.20.1的话,自己可以把我们今天讲的脚本再去用0.20.1再实现一下,好,那呃,这里就就多说一句,就是就是单元测试,我们主要是要什么,它主要重要的一点其实就是要保证我们每次测试都是独立的,而且都是隔离开的。所以我们一定是要起一个很。
10:25
很简单,很干净的一个环境做单元测试,因为我们没有想到要跟别人联调,要测复杂的这种生产环境,实际的这种应用,对吧?我们只是看这个模块,我们的合约到底是不是符合预期,所以我们需要一个非常简单的环节,所以呢,我们就不需要直接连到呃RO,不需要连到这些测试网络,甚至不需要本地起私链。呃,GALA就是最好的一种解决方案,就它直接提起来就是一个干净的,然后不用的时候关掉就没了,所以呃,大家知道GALA是基于我们内存来模拟的,对吧?它就跟在我们的remix里边,呃,不是这个remix里面,大家记得我们在run的时候有一个选项叫做javascript vm,就跟这个是一样,大家可以认为就是一个javascript vm。
11:19
好,呃,所以是啊,这里还提了一句,就是之前跟大家说过,白纳师前身叫什么,他就叫test rpc,所以呃,大家看很多的文章里边会介绍到test rpc都是拿它来做单元测试,呃,有些文章就是说,哎,我们怎么样去搭一个自己的项目呢?就是WEB3加GA加test r PC,我相信如果大家去网上搜过一些教程的话,很可能就见到过这样的教程,那其实test r PC就是我们做单元测试的这个GA纳SH啊好,我刚才说错了啊,不是那个GA纳是加test rpc啊,是就是呃,We web3加GA加test rpc对吧?一般情况它就是在test r PC上做完测试,然后去部署到就通过gas部署到我们的测试网络里面去。好,那么接下来我们来简单的介绍一下某场啊。
12:20
Mota它是一个JS的一个单元测试框架,它既可以浏览器环境里面JSJS嘛,既可以在浏览器环境里面运行,也可以在note下面运行,那在这个过程当中,我们就是不需要关心具体测试的各各种步骤,我们只需要按它的标准写测试用例,就我们只需要关注逻辑就可以了,所以具体的这些测试怎么样去判断是否通过,这是moa帮我们做的事情。那mota的主要特点是什么呢?它有这么三个特点,一个是既可以测试简单的JS,也可以测试异步代码。
13:00
那就是啊,等一下我们会看到啊,因为我们在真正跟合约交互的时候,很多是异步,异步的函数,异步的调用,另外就是它可以自动运行所有的测试,另外也可以就是只运行特定的测试,大家自己来配置,来指定,还有一个特点就是它里边支持一些关键字,就是生命周期,相当于是它里面有before after before each after each,有这些可以做一些初始化的测试代码,或者说就是完成之后的这些测代码,到时候我们用到的时候再说啊好,那么下面我们就来写一个简单的测试脚本的一个事例,好呃,我们大家就打开一个flash,我们来写一个文件吧,这里面我已经写了,先把它抹掉,呃,因为这个东西很简单,那我们就我就直。
14:01
贴在VI里边来编编辑吧,大家这个看着VI应该没什么问题对吧?好,呃,我们在里边首先就是我们这是一个JS,就是note下面执行的一个JS,大家可以想到就是我们直接可以写一个方式对吧?写一个方式,然后它的参数,呃,我们这个用了也是ES6里边的写法,这个是扩展标记符对吧?大家知道这个应该在go里边是不是也有类似的东西,呃,我我不太就是对go的语法不是特别的了解啊,所以大家如果熟悉的话,应该见过类似这样的写法,这样写法是什么呢?就是我们这个函数可以接收很多个参数,然后这些参数把它都保存为一个数组,对,就是扩展到这个rest这个数组里面来,所有。
15:01
参数都是这个数组里边的一个元素,好,那么接下来我们就我们这个函数主要是要要做什么呢?我们是要定义一个sum这样的一个函数啊,就是很简单,就是输入一串数,然后求个和,呃,那这个大家就想到了,那我们肯定就先定义一个总数是什么,对吧?首先它是零,这个大家肯定写过类似的求和函数,就非常的过一遍,那么for,呃,这个我们可以用,就是ES6里边的for for的这个这个这个呃,不,不是不是for each啊,就是for of的这种写法,对吧,去遍历一个呃数组里面的元素,那么我们let I of rest大家可以把啊。编辑起来确实还是有点麻烦,好,那么里边的话肯定就是some加等于I对吧?啊,那这最后我们就会return一个sum,就是非常简单的一个求和函数,那如果我们想要在别的文件里面去调用的话,或者想要用这个Mo查的测试脚本去调用它的话,那我们就不要指定它的函数名称,而是用export export啊。
16:30
module.export去把它直接export出来,然后在note的语法里边,如果我们直接去require这个文件,就可以把它就是拿到直接返回的这个方式,对吧?所以那么它的这个export就是一个返回值,就整个export出来的这个值就是一个函数类型,那么我们引用了这个文件的话,就可以直接调用它里边的sum这个函数了,好,这是我们非常简单的这个脚本,好那么我们写了这个sum脚本之后呢?好,这个啊,先把test这两个先删掉啊,好,呃,那么接下来我们需要去建一个test sum的一个脚本,我们想要用moa去做这件事情,那mota里边怎么?呃,首,首先我们先不用不用moa来做啊,我们。
17:30
我先看看,就是基本的JS里面,如果我们想写一个测试脚本,怎么去测。那JS里面其实是提供了一个,就是可以供我们来做自动化测试的一个库,叫什么呢?叫assert,就是大家熟悉的这个断言啊,我们comes的一个assert等于require asert,好,那下面我们肯定要把我们的这个函数拿出来,对吧?我们定一个sum就叫require。
18:09
呃,还可引起来啊some.js好,那接下来我们已经引入了这个sum这个函数,那接下来我们就可以用assert来处理它到底是什么样的状况了,Assert这个断言方法呢,它里边就可以去判断后面的这个值是否为真,那呃,它除了这个直接判断后面的值是否为真之外,还可以判断两个表达式是否相等,比如说我们这里用一个它的这个方法叫strict equal,这个东西是什么呢?那strict equal就是我们在JS里边的这个三个等号这个意思,那一口的话就是两个等号,对吧?大家应该讲过,它这种就是就是这种强等于三,三个等号这种类型判断,那么它里边就直接可以给出两个表达式,比方说我们直接调这个sum,那不给参数的话,就相当于我们。
19:09
传定的参数是空的对吧?那空的正常情况下它应该返回一个零,这是我们想要做的,好,那接下来我们可能还要多写几个对吧,多写几个测试的情形,那么SUM1的时候只穿一个一,那肯定他应该返回一,那third这个就大家随便写啊,我这里就是给最简单的例子,二的话,呃,1SOME1,二的话,后面我们其实想让它等于三对吧?对,所以是加这个叠加一二,大家如果还想写的话,我们就再加一个123,大家看到我例子里面也这么写的,3123,那这个加起来是六对吧,如果我们想。
20:09
还要要让它正确的话,应该是等于六好,那么我们看一下保存一下,怎么执行呢?直接test subjects对吧?诶大家看直接就执行完了,那所以说在这个我们如果直接用note里边给我们内置的这个断言方法的话,那其实自己还要写很多很多这个判断的条件,对吧?那比方说我们这里可能就需要我断言完了之后,那我再文素点LOG1句说比方说我说or aer past,可能可能我会加这么一句对吧,来表示它真正的执行完了,那我们这个执行完了之后会发现能输出这么一句,那大家可能想到那这个我根本不知道他到底什么情况啊,如果说我这里面错了的话,会怎么样呢?假如说我们这个123,我给一个给个五吧,假如说我,我是想让他assert这个S。
21:09
123等于五,这个会出现什么情况呢?啊,那就是本身sir这个方法大家会看到,如果它判断的两个不相等,不符合我们给定的条件的话,它是直接报出报一个错,就相当于我们程序执行出错,然后他直接抛出来,他说的这个error的类型就是assertion error,就是断言错误,呃,所以大家看到这个这个可读性,它是直接抛出异常,我们其实是希望它能完整的执行完,对吧?你如果这里抛出异常的话,大家就会发现,那如果我们这里是给了一个五是异常了,那假如我们第一个就异常了呢?我后边都是对的,我第一个SUM0就给一个一,那大家就可以看到它直接零等于一,第一个就异常了,那大家知道抛出异常的时候,后面肯定不会再执行了,所以相当于我们这个测试就就只测了一个,那我们得一个一个再去顺序调,这是很不方便的。
22:09
那整个这个呃,就是这样的,不方便我们怎么样去解决呢?Mota就可以就可以完成这个事情啊,就是我们可以用用牧场来做这件事情啊,那么现在我们在把这个some test sum,这个JS,我们再稍做一些修改,我们用sum的这种,呃,用用这个mota的这种方式来给大家写一个测试脚本,Mo的方式怎么写呢?它里边直接可以有一个关键字叫做describe describe是个什么东西呢?它其实就是描述我们一套测试的流程,测试的脚本,所以经常我们就用describe把它把一一整段流程把它框起来,表示这是一组测试啊,所以我们可以比方说里面加一个井号去表示它的这个类型,对吧?我们比方说我们要测的是sum JS,然后后边呢,它就用回调函数的形式。
23:09
呃,用这个箭头函数啊,用回调函数的形式,把它要测的内容直接包裹在里边,那同样这个describe是可以嵌套的,我们可以任意的嵌套,里边再写一个describe,也就是说一组测试里边还可以再分组,对吧?这都是非常直观的一些语法,所以跟大家一说再敲一遍就知道了,里边同样还是可以再去给这样的一个回调,然后把我们的一组测试包在里面,那里边具体的测试怎么样去写呢?它有一个关键字叫it啊,It是什么呢?其实就是说它应该怎么样,对吧?每一个it大家就可以认为是一个测试,一个单元测试好,那么it里边他做什么事情呢?它首先给一个描述,比方说就是it some数的。
24:09
呃,RETURN0吧,好,那么接下来同样它的这种风格也是一个回调形式的风格,呃,接下来我们看它的函数体,那函数体就是直接调这个我们的aer这个断言了,对吧,Assert点还是跟跟下面这个之前写到的一样啊,Strict equal。三一啊,这就是我们一个简单的一个单元测试,那所以大家想到了,那下面的这个单元测试怎么去做呢?我们同样还是可以把它我就直接复制了啊,大家可以手敲一遍,大家可以把刚才的这几个单元测试都写在这里,比方说我们呃,我要求这个SUM1,它应该返回一,那么我们这里就assert啊,这个上面应该是零是吧,就应该照着下面超成一,同样我们下面还可以assert some,呃,就是数的一二,数的RETURN3,那么我们这里给一个一二,这里是三,那同样下面123应该是六,对吧。
25:38
12316好,下面的这几行我们就可以删掉了,那大家可以现在看一下这个啊,当然大家可能想到,那我现在如果要去直接弄de test some的话,那肯定就会报错,为什么呢?因为node里面没有describe关键字,对吧?我们也没有像node风格一样,前面require一个什么东西,然后里边有describe,那这个应该怎么去用呢?啊,那我们就直接用Mo场。
26:16
来来执行就是它的执行呢,就是直接调用Mo,它的调用风格就是我们。哎,这个为什么会有这么一个提示,我们直接调note modules里边的Mo叉,然后它下边会有一个BMO,好,那么呃,这样的话我们可以去执行这个test sum JS啊,所以大家可以看到后面跟上我们想要去指定的执行文件,然后它就会给出一个我们执行的结果,大家可以看到前面就是我们给定的描述,然后后面就是我们it后面描述的每个单元测试。
27:02
然后它会显示如果通过的话,这四个都会打勾,然后四个PASS42毫秒对吧,那我们就就再把它改一个,我们看看如果说前面有一个错了,它会怎么样呢?我们这里改成一看一下好,还是Mo test sun JS好,大家可以看到它的错误的返回后面不会被阻塞入对吧。他只是告诉我们说,第一个这个红色的就代表这个测试失败了,然后我们看到三个passing,一个falling,它会很明确的告诉我们到底在哪出了问题,然后抛出这个异常零不等于一,所以说这个我们断言失败啊,这就是Mo察的这个框架啊,其实是非常简单的一个过程,呃,那在这里再多说一下,就是moa默认的。我们其实可以不这么去指定这个test sum这个文件,我们可以直接就moa,那moa直接执行的时候,大家会发现它是需要一个路径叫test,所以如果我们想要统一去写很多个测试脚本的时候,用工可以去创建一个叫做test的一个文件夹。
28:20
那么我们把我们写的这个测试脚本直接放到这个test目录下面去,那么在这里去直接猫查,他就会执行我们这里面的东西,但是大家会发现这里报错了,这是因为我们路径没改对吧?我们到里边,我们到里边去改一下路径。Test test这个大家看到这里就不能点啊,我们上级目录的对吧,好的家再直接入场一下可以看到,就又会直接它会直接扫描我们跟目录项目跟录下面的test文件夹,然后把里面所有的JS文件全部执行一遍,用mota框架去执行一遍,返回给我们它的出错的结果,好这就是整个mota的这个这个框架。
我来说两句