WEBASSEMBLY UNIT TESTING | Introduction to WebAssembly (WASM)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back and in this video we're continuing our deep dive into webassembly and today we're going to focus on how you unit test your wasm files using jest so before we jump into unit testing our wasm files the first thing we need to do is create a webassembly module that we want to unit test now what we're going to do in this example is we're just going to very very quickly hand code a square function and that's the same square function that we've used in our previous videos and if you want to deep dive into how that works then just click on the link on the top right hand corner and then you can get a full explanation on how that works but very quickly we'll just hand code it up and get it working and then i'll show you how the unit testing works again i'm going to be super lazy i'm just going to make this work in a node.js environment of course because it's webassembly it can work in node.js it can work in dino it can work in standalone or it can work in browser but for laziness sake i'm just going to very very quickly create it in node.js to show it working so the first thing i'm going to do is create my node.js project so let's just create a new folder for that so we will call it um square unit test a really imaginative name there as you can see there and then we'll just see the into that and there we go we've got an empty folder and now what i'll do is very quickly just create uh my node.js project so i'll run npm in it i'm just going to hit return lots of times and as you can see that is now created and what i will now do is just create a new file called index.js and that's going to be our node.js app which we can execute to run our webassembly module and the next thing that we're going to need of course is a webassembly module and in this case because it's a math function we will create a math webassembly module and we're going to code that in webassembly text format again i cover all of the details of that in one of my other videos but we will very very quickly create it now so i'll just go touch math.what which stands for webassembly text format and now what i'm going to do is open up in vs code so we can get coding on it so we'll just type in code dot and that will open up vs code into the folder that we created so as you can see there i've got my index.js i've got my math.what and i've got my package json so in mymath.what what i am going to do is very quickly hand code this module so in webassembly text format you need to create module as a starting point and that represents a module in webassembly now for javascript programmers that's basically the equivalent of an es6 module it works in exactly the same way and in fact you can export functions from webassembly modules so that you can call them in javascript and you can call at javascript from your webassembly modules as well so it works very very similar okay so we've created that and the first thing i need is a function so that is represented in webassembly tech format as a func and i need to give it a name so in this case it's going to be called square and because i'm going to square a number so just for anyone who's forgotten their math right squaring it is just multiplying a number by itself so if i uh try to multiply 10 square 10 then 10 multiplied by 10 will come back with 100. so i need to pass it in there for a parameter which is param in webassembly text format and of course i need to give it a type because webassembly modules are a static language whereas javascript is dynamic webassembly is static so i need to specify what the type is that i am working with so in this case it's going to be a 32-bit integer so that is represented as an i-32 so i've got my parameter and then of course i need to give a result as well so i'm going to call it result and again that's going to be a 32-bit integer so what i've got here is a function func which is part of a module and that function is called square and it's got one parameter which is a 32-bit integer and it's going to return a result and if i wanted to make it even simpler i could just give that parameter a name so in this case i will call the parameter number so nice and simple so now i've got my func what i now need to do is do the squaring operations so again i explain all this in my other video but but let's be super quick about this so what i need to do is get the number that i passed in from a parameter so i do that using local and there is a local.get and then i will specify the name of the parameter that i want to access so in this case it's the number now because webassembly is a stack machine which again i explain in one of my other videos on all about stat machines and how they work and how webassembly operates as a stack machine but essentially what's going to happen is i am going to take the number that i've passed in so that's the local.get and then it's going to push it onto a stack so my stack should have whatever number i passed in the first time now of course because i am squaring a number i'm going to do a multiplication 10 multiplied by 10. so i need to multiply the number by itself and because webassembly is a stack machine what i need to do is have the two numbers i'm multiplying together on the stack right because that's how the multiplication function is going to work it's going to take two numbers off the stack at the moment i only have one number because i've pushed on to the stack the number that i pulled as a parameter so to multiply it by itself all i really need to do is do a local.get again and get the number a second time right so now having done that i'll have two items on the stack which will be the number that i pass in twice and then finally to multiply these numbers together then i'm going to call the multiplication operation which is i32.mol and as i said what that operation is going to do it's going to pop two items off of the stack which in this case it would be the number 10 twice or our parameter number that we've passed in twice so pop that off twice and then it will multiply them together and then it's going to push the result so in this case the result would be a hundred it will push that back onto the stack so i had two items on the stack now i have one item on the stack and finally what we need to do is return the result of our multiplication or the square from the function and the way webassembly works is that whatever item you have on the stack whatever's on the top of the stack will be popped off and returned uh when the function ends so in this case we have one item on the stack which is the result 100 and that would therefore be returned with that result parameter here so now that we've got our square function like a module in es6 what we need to do is export that so it can be accessible to any calling programs in our case node.js so to do that i just need to create an export and then i need to give my function a name so in this case i'm going to call it square just like i did before and then i need to say the function that i am going to be exporting so in this case it's going to be funk square and that is all we need to do and we can just save that and we've got our square function so next thing i need to do is compile my webassembly text format into wasom's bytecode format and i do that with the webassembly binary toolkit and in particular the wac to wasm tool now again i explained that in my hello webassembly video um but i have the webassembly toolkit already installed on my machine so i'm just going to run that but if you want to see how to install that see my other video so i just need to call orbit bin and it's called what to wasm and i need to put in the name of my webassembly text format file which in this case is math.what and then i want to output that that's the minus o as a math.wasm file so if i hit return here it will have now generated the math.wasm file in my folder which is cool alrighty so now that we've created our math.wasm file what we want to do is just quickly execute it in node.js make sure it works before we then create a unit test so to do that i'm just going to do a import fs from fs and the reason i'm going to do that is i'm going to do a text file read of my ysom files so i will therefore do a const wasm equals fs dot read file sync and the name of our file in this case was math.lasm so all that's really doing is loading the watson file that we created into memory essentially and what i want to do now is put that in a buffer so we'll call const buffer equals new uh u and 8 array and we will pass in the wasm so we now have that and then what i need to do is essentially instantiate my webassembly module so i will give my module a name which in this case will be math and then we will just await a webassembly call and we'll call webassembly.instantiate we'll pass in my buffer and then we will get access to the exported function so press res.instance dot exports nice and then finally all i really need to do is call my function so if i go console.log and then i can go math dot whatever the name of the function i created so in this case it was square and then i'll pass this through a number uh that i want to square so in our case it will be 10 because my tiny little brain can cope with that i can do 10 times 10 any other number i'm gonna struggle with so we'll do that and the final thing we need to do just because i use the import statement i just need to change my package.json so it says type is equal to module so it can recognize es6 modules and then we'll just save that and now for unknown index.js then it should come back with my square so nodeindex.js and you see it returns 100 and then i can change any value that i want so i could put that equal to 5 and that should come back with 25 which it does and now that we've got a working webassembly module that we can call from node.js we can create our unit tests around that now in reality you should be doing that the other way around right test driven development you create your unit test first but i wanted to just really quickly get everybody up to speed on what our webassembly looks like and then it will make more sense on how we integrate our testing framework so we've done that now so what we're going to use is just as the testing framework so to do that we need to install just on our machine so to do that i'm just going to type in npm install and i'm going to do a save and i'm going to do dev right dash dev as well because i want that to be a dev dependency rather than a production dependency and then i'm just going to type in jest and it will install just on my machine and then add that to my package.json so that will take a couple of seconds to run so now that jess is installed what we'll do is create our unit testing files so i will just add this and we'll call it math.wasm.test.js so that's created and essentially what i'm going to do is recreate the code that i had in my other file node.js but i'm going to put that into my uh js file alrighty so what we're going to do quickly is just copy and paste what we created in our node.js index.js file and then we're gonna re-jig that a little bit to work uh for the jess framework so all i really need to do is paste that in here because chest kind of struggles with the es6 modules and the import statements we need to use the old uh common modules um from es5 and below so uh so we'll just type in const fs equals require uh uh fs and that will make that work and of course i think in a future version imports will be supported in the js framework and i think it's in beta just now i just don't want to mess around with my machine there so the next thing i need to do is just load up my webassembly module first before i can execute my test so to do that ingest all i really need to do is call before all and then it's going to be an async function that we are creating so i will just create my arrow function here and we'll just do that and then what i can do is uh copy this law into here so if we just do that a second uh tidy that up a little bit and there we go now probably one of the differences is because i'm going to execute my tests outside of this before all i really don't want to scope my math variable into into the scope here so i will just remove the const there and then what i'm going to do here is just do a let math at the top make that global and then i can access it from with in the test so i've done that now and we'll just hit save and then all i really need to do to test this is start uh creating um some functions so we will do test and we'll say we want the square of five because my tiny little brain can cope with squaring five i think that should be equal to 25 and then what we will now do is we'll create another arrow function here and we are gonna expect um the s math dot square uh because that's the name of our function and we would expect this square of 5 to be 25 and the next thing i need to do is just update my package.json so that it uses jest as its test runner rather than be nothing so if i save that and now if i run npm run test or test pass and of course if i go back in here if i put that to 20 for example we should see a failing test which we do so if now all i can do now is just create as many tests as i want so my tiny brain can cope with 10 we would expect that to be a hundred we would need also expect the square of one to be one and i'd expect the square of 100 to be uh i have no idea 10 000 maybe uh just run that and then run my test and it all fails hey it turns out the square of 100 isn't uh 10 uh well it's not 1 000 anyway it's 10 000. alrighty um we just uh we need to put this equal to 10 this should be one uh this should be a hundred and then if we just run our tests and they all pass and there you go that is how you unit test webassembly modules you would essentially use jest and unit testing exactly the same way as you would before in a javascript framework but instead of testing javascript you're going to be testing these wesser modules that you create but the framework remains the same all the js functions remain the same and you would do everything in exactly the same way anyway i hope this has been useful and we'll speak soon in our next video
Info
Channel: Chris Hay
Views: 164
Rating: undefined out of 5
Keywords: chris hay, chrishayuk, unit testing, unit testing javascript, unit testing webassembly, webassembly, web assembly, wasm, jest
Id: LsbEGkucCaM
Channel Id: undefined
Length: 16min 47sec (1007 seconds)
Published: Mon Jul 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.