00:00
之前写的合约来做一个,就是一个框架性的一个测试,这跟我们之前的测试脚本其实是有非常相似的地方啊,那我们这里边主要是给大家介绍两种不同的测试框架,或者说是这种测试方法,那这两种是一种是基于solidliity的,也就是说我们直接去编编写solidity原文件当做测试文件,呃,就像大家熟悉的其他的一些编程语言,像Java啊,或者是其他一些编程语言,它都是自己写一个类,然后就可以写一个test。Class对吧,就是一一的对应这种单元测试去写,所以这是solid的一种写法,另外还有一种其实是大家比较熟悉的jascript的写法,那这个其实就是要用到moa框架,所以插里边也是内置了内嵌了一个moa的,呃,那当然了,他用这个谋产的方式呢,跟我们就是在外面直接之前写测试脚本的时候,那种用法还会稍微有一点不同,因为他又包了一层,那接下来我们就来看一下,就是在我们的这个呃窗口里面到底怎么样用它的这两种测试框架去写单元测试,呃,那在这里边给出来的这种。
01:22
经验性的一个总结是什么呢?就是一般solidity用来写单元测试,也就是说我们简单的一些一个模块,然后一个简单的合约,写完了之后就匹配对应有一个test。Solidity的一个文件,那这样的话做这样的单元测试,JS这边呢,因为它更灵活,然后有moar的,所以它更适合写功能测试,就我们可以把场景串起来,写的更复杂一点,所以这是一般的这样的一个应用场景,好那么我们接下来就准备实现一个就是solidity里边的测试文件,然后再写一个JS的测试文件,那其实就是基本的这两种测试方法,我们就相当于都了解了,好这个东西比较简单啊,所以我们就是在这里只是简单的给大家来演示一下就可以,好那么接下来我还是这样啊,我开一个。
02:24
去先创建一下我们的创建两个文件。首先到我们这个目录下来,大家注意,在我们所有的测试文件呢,都会放在窗口下面的test这个文件夹里,这跟我们之前那个moa的那个模式是类似的,对吧?Moa也会自动去检测当前在test文件夹下的东西,所以这里边我们所有的测试文件都会放在这个呃,太子文件夹下,我们先瞄一眼这个。本身它自带的这两个到底长什么样子,对吧,Test。
03:06
我们看到这里首先有一个ma com.JS这是JS写的测试文件,另外还有一个叫做呃,Test ma co.oll那当然这个就是一个呃,Solidliity源文件的测试文件了,对吧?但是大家又看到就是它上面这个不完全是solid的语法,所以它上面还有import,对吧?那这样的话,其实它会呃,呃,当然这个import,这是我们相当于引入了另外一个合约,别的一个合约,那这个合约这个在哪儿呢?那其实这是travel框架里面的东西,所以说他要引入travel,其实是相当于给我们包了几层东西的,比如说这里有assert,比如说有这个deployed addresses,这些都是travel里面的东西,好,那么我们这样吧,这个就更简单一些,我们直接在这个基础上去做一点改动好了,对吧,这里有一个test me Co,那我们直接就改一个名字叫test voting好了。
04:06
呃,大家注意一下,在这个框架里边,它所有的测试文件都放在test目录下面,另外就是扫,如果要用到窗口框架去做测试的话,扫原文件必须以test打头。啊,这个大家注意一下,而且大家注意里边这个合约名称也是要一样的,对吧,Test voting,然后我们把这里的这个原文件也就给成voting,好把这个改一下就可以了。然后大家就可以看到,我们接下来有两个方法,呃,比方说大家可以看啊,这是本来这个ma coin这一个测试里边它用到的一个例子,它怎么去测呢?它定义了一个test initial balance using deployed contract,对吧,这就相当于是要测一开始的时候合约的一个,呃,就是一个里边的一个值,对吧,以initial手的这个balance要要测这个里边定义好的这个状态变量。
05:13
那同样我们其实也有一个对应的一个状态变量,对吧,就是我们voting这个合约里边其实默认是给了一个我们提供的token,一共有多少这个的,那其实我们就可以照着它来写一下,这都不用改,我们给的默认的初始值也是1万对不对?所以我们这里边直接可以定义一个expected疑问。那这个代表什么呢?这就代表等一下我们要做断言时候的一个对应的参考值,也就是说自己的期望值对吧?好,那么接下来我们肯定就要去,它这里是ma po,那我们就得定义自己的一个voting了,对吧?那同样后边voting我们也小写的定义一个voting对象,那后面怎么写呢?它这里是ma coin,大家注意啊,这里我们就要用voting。
06:05
这相当于是不是做一个强制类型转换,大家看后面是一个address,对吧?Deployed addresses,所以下面是要拿到我们真正部署上去的那个合约的地址,Travel帮我们管理了这一切,所以这里拿到地址,然后我们用voting这个类型去给他做一个强制类型转换,就转换成了我们的voting合约。所以前面我们定义了一个voting合约,它就等于这样的一个东西,就把我们那个voting部署的那个合约地址拿出来,这就是我们的合约实例。大家。理顺这个它的逻辑是什么样子的,那当然就是后面我们这肯定就是把ma Co改成VO就完了,对吧?好,这是我们这里的这个就是前面先定义好我们的合约实例,那接下来大家可能就知道了,我们要想测的时候怎么去调用呢?大家看它这里边的balance是什么呢?就是定义好的那个medical Co,直接就调用它的方法,Get balance。
07:10
大家如果要是对这个感兴趣,可以回头,我这里边是删掉了,大家要没删那个ma的原文件的话,看看他合约到底怎么写的,所以这其实就是调用一个方法,然后还给了参数,对吧?所以这里边我们也可以就像他这样去做,那我们的voting里边有哪一个是可以直接拿到的呢?就是我们一开始给的那个token的那个balance,对吧?去到原文件里边看一眼,原文件里面我们定义的这个balance叫token balance,所以这是一个public类型的变量,那。我们这里就可以直接用这个方法去调用了,对吧,诶不是token balance啊,这个我们要测的这个1万应该是它的总数对吧。总数那应该是total tokens啊,这个大家注意一下啊,这里是我们写死的一个值,所以我们用这个角色,然后后边给上这个except,这就是大家可以看到这个熟悉的这种断言的方式,对吧?跟JS里边load里边的这个assert断言是一样的,就是断言assert.e后面两个值是否相等,voting.total tokens,那这个它直接会拿到就是这个反馈值去做这个对应的处理,然后呢,跟这个expected expected做一个对比。
08:36
最后是这个就是我们输出错误的这个信息了,对吧,我们比方说这里我们应该说一个什么呢,就是。就是,呃,应该是total。字数的比1万对吧,这就相当于是我们的一个输出的一个错误信息,假如说我们这一条断言没有通过的话,那我们就输出这样一个东西,所以大家可以看到,其实这个东西就写起来非常简单啊,当然这个我们是只做了最简单的一个调用,就是去查看当前的total tokens,大家肯定想到,那我们比方说我要去测试一下我当前能不能买这个。
09:24
Token怎么测呢?那它这里定义了一个test什么什么东西,咱们就定义一个,咱们就肯定不是initial了,对吧?比方说test by tokens,我们要测一下它到底能不能买,那这个东西怎么去测呢?大家会发现还是一样的东西,对吧,前面也是得定义我们的这个voting。拿到合约实力。当然了,后面这个我们就不要去new了。我们还是去把它deploy一下。
10:00
直接复制过来voting deployed addresses.vo.voting里边的这一部分,大家就会发现这其实就是我们的合约地址,然后外边的这个呢,就做一个强制类型转换,把它转换成一个合约对象,好这就可以了,然后这里的呃,我们expected就先不写啊,我们在这里会去,呃,直接去调用一下voting点。BY对吧,应该就叫BY的那个方法,然后去买多少呢?呃,这里大家注意啊,这个写法是点value,然后给上它的值,比方说一个这里是solid的写法对吧?所以就是方法后面可以直接跟点value.ga这样的修饰器的,大家还记得吗?这是扫的写法,不是JS的写法。所以里面是可以不用做那个转换,我们直接跟单位的对吧。
11:04
一个以态,所以这就是直接去买这样的一个以态。呃,所以我们这里传了一个以太进去,那按照我们的规定,这就可以买到100个token,那我们现在是不是expected应该就剩下9900个token啊,所以大家看啊,我们这个测试也是就是重新把它部署了一遍,对吧,然后重新去,就是相当于一个空白的环境去做这样的一个处理,然后当然最后的这个,呃,这样的一个测试,我们是要测试当前它的。Voting,我们有一个方法是拿到当前的余额,对吧?Token balance,对,现在是token balance,所以token balance好,这样就可以了,然后直接调这个方法在扫里边,它就直接会返回一个unit,对吧?所以这里我们就不需要去做后面的处理了,大家不要还想着后面直接就去点赞对吧?那个是JS里边的promise的调用方式,我们这是solid,搞清楚好,那接下来这个是expected,那后边我们就说。
12:16
呃,比方说说这个con balance should be 9900,比方说after。一个ETH对吧?好,我们把它保存一下,然后接下来大就会发现我们就可以去做一些,这个就直接可以运行了,那在travel里边我们怎么去运行呢?其实也是非常简单啊,如果大家直接在这个根录下直接去运行travel test的话,它就会自动去执行我们test下面所有的测试用例,那如果我们想要去指定某一个的话,那我们test不是medical诶。
13:04
这个名字没有改过来哦,所以这个还是应该还是这个,我把这个退一下啊,可能还是跟我们现在的这个,就是我这里边虚拟机的这个环境会有关系,好我们这里的这个server就不要了,对吧,我先退一下啊,然后。退掉所有的,然后重新进去看一下。大家自己的环境应该是没有这个问题的,把这里挖矿也停了,大家可以想到等一下我们最好是用什么样去做这样的测试啊。其实我们用GA就可以对吧,或者是大家直接用那个,呃,就是travel develop也可以,那大家知道我们在travel develop里边,它其实也就是内嵌的一个盖纳,对吧,大家应该还看一下这个。
14:01
啊,现在是了,对吧,现在对了好。我们直接敲travel test,然后定目录,然后指定我们对应的这一个文件就可以了,那当然这里现在肯定会有问题,为什么呢?因为我们没有起对应的这个节点,对吧?所以我刚刚把节点关了,所以我们在这里再去。起这个GA纳就随便起了,因为之前大家已经在一些模块里面可能装过这个GA纳,对吧,在随便找哪一个把它提起来也就完了啊,那这边肯定已经报错了对吧?没有办法连接到你的以太网节点,所以我们这边先起一个GALA,它会自动给我们生成十个账号,这个跟传统d develop的行为完全一样。好,我们看一下这边会有一个什么样的状态啊。啊,大家可以看到这边已经在编译啊这几个,哎,这里报错了。
15:05
我们这里好像写错了是吧。Booing点败。Forget。我们的voting点难道不是payable的类型吗?哎,这个会会有点奇怪啊。哦啊,大家看到我这个错出在哪了吗?这个比较也这个也是比较容易犯的一个错误啊,就是在扫里边做这个调用,跟上value这个修饰符,表示我们这个调用的时候发多少以态的时候,大家注意啊,前面不能直接加括号把它调用了。因为调用完了之后,相当于已经拿到的是返回结果,对吧,你再去点value,它肯定就有问题了,所以这个value是我们Y这个方法的一个修饰器,所以大家要注意把这个括号要去掉,这个地方大家稍稍微注意一下,当然就是也可以点GA对吧,去设定一些,呃,这个指定的GA值好。
16:18
我们再去跑一遍。在编译啊,我们同时看一下这边。点这边的一个情形,好,这边已经生成交易了,来看很多个交易啊。这边已经通过,诶挂了啊。我们看一下报什么错。啊,一个过了,然后一个有问题对吧,他是tested得到的是1万,然后against是9900,所以说明我们这个好像没有没有购买成功是不是好,我们检查一下我们的代码。
17:03
好,我们看一下啊。这里边我们去做了一个操作。Voting点拜点value。好,刚才哎,你看这个就是改了一个问题,然后又忽略了另一个问题,大家看这是什么问题呢?就是我们后边这个点Y6只加了一个修饰器,对不对。只加了一个修饰器,但是事实上我们这个BY还没有执行对吧?我们前面加括号,这样是执行执行了BY,但是这个后面的点value,这个修饰器就生效了,那我们直接在Y后面加上点value,一个ETH的时候,确实这个修饰器是生效了,但是呢,我们的BY没有执行对不对?对,要执行的时候后面得加上括号,再注意一下这些细节啊,也确实S里边这些东西很容易错,好重新再执行一下。
18:10
呃,这个确实平常我们很少直接去这么写的测试文件,对吧,所以这个可能就是大家也会不太熟悉,到时候尽管简单,自己最好是能多写几个,然后把这个都都实现一遍,然后看一下这样它的这个效果是什么样啊,大家可以看到这边已经跑完了啊。哎,这边又出错了,看一下。呃,交易出错了,我们看一下这边是哪一个交易有回滚的状态。交易回滚。这个出错信息很,就是这个出错信息它非常少,其实是比较难判断的,对吧,那这种情况其实很有可能是他在执行的过程当中,我们先看一下这个voting里边的BY是不是有这个条件判断。
19:09
我们只判断了要小于等于它的token token balance。我们现在要买的这个量应该是不会超过对吧,Token price。这里我们给一个,难道这里给的有问题吗?我们很明确这里给的是。哦,大家这里可能就又要注意一下了,就是我们在这里的话,应该这个,诶我们看一下是不是这里变成了鬼啊。message.value我们这里边定义的,这里边传进来的应该是一个伪的值,对吧。
20:05
然后我们的token price。应该也是一个尾的值。所以这个看起来应该也没有什么问题,对吧?诶大家能想到这个问题在哪呢?我们还是对照一下我们的课件吧。这个出现问题的时候找源码对照啊,我们看一下课件里边这个怎么实现的floating,这个没问题对吧,Deploy。Floating点败点value一个以态。Vo.balance token,就是它的方法跟咱们定义的不一样,对吧,跟我这里定义的不一样,Token balance。啊,它是没有定义这个expected对吧,但这个应该应该一样的,对吧,大家觉得这个应该是没有问题吧。点e expected,你在回过头来看一下这个测试出错啊,它是在执行一个交易的时候去,所以应该还是我们在拜的时候出了问题,对吧。
21:13
Token,我们的token这个有问题吗?拜的时候,这个要去捡。看起来应该没有问题对吧,我们直接copy一下这个代码看一下啊。我们把上面的这几行先注掉。
22:02
呃,这个其实如果我们直接在这里目测的话,感觉应该是没有什么问题的,快点value来比对一下对吧。一个以太下面equal。呃,我们直接这么写一下,先照着这个测一下看一看,看看是不是这个expected的影响啊。因为我们的有可能有什么样的问题呢?大家能猜到吗?又搞错。太pleasure了,好对我没有这个number,这个照抄这个还是不好啊,好好现在这边交易生成。
23:14
还是报错这个代码也不行,大家想一下,咱们这个过程当中还缺什么东西啊。我们看一下课件,这里面应该是把这个说出来的啊,大家注意一下,在这个,呃,就是大家看一下啊,就是在这里专门说了一句这个test by token。就是你必须要提供一个initial balance,为什么要提供一个initial balance呢?因为就是我们的测试合约,它是必须要有一个初始的balance,然后你才能够用它去买的,它不是直接用我们默认的就GALA里边的ACCOUNT0或者是哪一个去去用的,因为把这个都已经给我们包起来了,所以相当于是说我们一开始是trouble给我们建立了一个这样的一个账户,一个对象去做这件事情的,你假如不指定这样的一个,大家看到这里有这么一句,对吧?
24:16
你如果不指定这个initial balance的话,那么tri就认为你的账户里面没钱,所以这也是很很坑的一个地方啊,给我这些就是坑,经常都得是经常踩啊,常常踩常新。所以you in public,然后一它叫什么initial,这个名字还不能错,必须得叫这个名字啊,Initial balance等于我们给两个或者三个以态。然后之后转一个以态就可以了,对吧。这是方式没问题吧?好,现在我们再来试一下。好,他在提交交易哦,我们终于等到了两个pass啊,好吧啊,所以大家可以看到就是在这个过程当中,还是就是有这些很细小的点需要去注意一下的,另外还有一个就是大家注意一下gas,就像现在的话,我这边应该是我看是不是我调过gas啊,窗口点GS啊,我这里调的这个是650万,默认的是比较大的一个GA,因为大家看到,如果大家要是在这里测的话,有可能会遇到auTo Ga的一个错,因为这里有一个合约部署,对600多万,所以这个大家如果要去直接按照自己默认的值的话,肯定是会就是auTo Ga的。
25:38
所以这个也是需要注意的一点。
我来说两句