Placeholder Image

字幕表 動画を再生する

  • [MUSIC PLAYING]

  • JORDAN HAYASHI: Hello, and welcome for lecture 12, deploying and testing.

  • So last week, we talked about performance.

  • We talked about the trade-offs that you get

  • when you do some performance optimization, that

  • just being additional complexity.

  • We talked about a couple of different ways to test against performance, one

  • being the React Native perf monitors.

  • So it's built into your phone, and it allows

  • you to see how many frames per second you run.

  • We talked about the Chrome Performance Profiler,

  • which actually runs your JavaScript code within Chrome

  • and shows you a flame chart of all of the components that are rendering.

  • We talked about a few different common inefficiencies that we see in React.

  • One would be re-rendering too often, another

  • being unnecessarily changing props, which may actually

  • contribute to re-rendering too often.

  • And then lastly, just unnecessary logic.

  • And then we ended the lecture with a demo

  • of this animated API, which allows us to run

  • some calculations on the native side of things rather than within JavaScript.

  • So this week, we'll give a high-level talk about deploying apps.

  • So the way that you deploy in Expo is by building the app locally, and then

  • uploading it to the store.

  • Before you do that, you have to make sure to set the correct metadata

  • in your app.json file.

  • And you can find out exactly what those are at this Expo documentation link

  • here.

  • Then you go ahead and build the app using

  • this command-line utility called exp.

  • It's basically just an alternative to the XDE

  • because the XDE does not allow you to build the app within that GUI.

  • The way to do this is to install the script.

  • So you do npm install global exp, just like how

  • you install a bunch of other libraries.

  • You then build it by doing either build colon iOS or exp build android.

  • What that does is it actually sends your JavaScript--

  • your whole bundle, actually-- over to Expo's servers,

  • where it does the entire build.

  • And then Expo uploads that build to S3.

  • The way that you get that build onto your computer is to run this [? ex ?]

  • [? build ?] [? status, ?] which if you run it while it's building,

  • it will let you know it's still building.

  • But once it's done, it will spit out a URL for you,

  • which is the link to your app in Amazon's S3 storage system.

  • And then you can just cut and paste that into a browser

  • and go ahead and download that file.

  • Then you can upload it to the appropriate store.

  • So the way that you do that depends on whether you're doing iOS or Android.

  • And here's a couple of documentation links

  • that talk you through that process.

  • One great thing that you can do with Expo

  • is to deploy new JavaScript by republishing.

  • And that's called over-the-air update.

  • So you actually upload a new bundle because the way that your app works,

  • it's really just a shell that's running JavaScript code.

  • And so you can go ahead and download some new JavaScript from the web

  • and run that as your application.

  • And so by republishing from the XDE or using that exp script,

  • you can deploy a new JavaScript bundle and push it

  • over the air to your clients without having them redownload

  • the app from the app store itself.

  • Though if you want to change any application metadata,

  • like the name of it, then you're going to have to resubmit it to the store.

  • So doing this over-the-air update thing is very, very powerful,

  • but also slightly dangerous because you can actually upload JavaScript

  • that crashes your app and doesn't work.

  • And it won't actually be caught by their respective app store people

  • because they never see it.

  • It just goes straight to the cloud.

  • And then your users go ahead and download that.

  • And so how do we ensure that everything works as expected before deploying?

  • So you do that by testing.

  • And so when we use the word "testing," we generally

  • are referring to automated testing as opposed

  • to manual testing or doing quality assurance,

  • whereby you just open up your app manually and play

  • with all of the features that you have to make sure

  • that they work appropriately.

  • And so why might we want to do this?

  • Well, as your application grows in size, manual testing

  • gets more and more difficult. And more complexity

  • means there are more points of failure.

  • And so if you imagine if every single week,

  • you add 10 more features, that's growing linearly every week.

  • And so even though you keep adding the same number of features every week,

  • the amount that you have to test every week actually

  • goes up by the integral of that.

  • So you have a linear growth in the number of features

  • that you have to test every single week.

  • So by adding a test suite, you can ensure that you catch all of your bugs

  • before they get shipped.

  • Because the last thing that you want to do

  • is actually upload some broken code, because then all of your users

  • will get a broken app.

  • But how do we know which parts of our app to test?

  • There's this theoretical structure called the test pyramid.

  • And it determines a methodology for determining test scale or granularity.

  • So at the very bottom of the pyramid is what's called a unit test.

  • And this tests an individual unit of code.

  • And generally, that's either a function or a class or a method.

  • Then you have integration or service tests,

  • which allow you to test the integration of multiple of these pieces of code

  • and how they work together.

  • And this is completely independent of the UI.

  • Which brings us to the last one, the UI tests, or end to end.

  • And this allows us to test a feature thoroughly,

  • including the UI and network calls and everything.

  • So it's basically from one end of your code all the way to the other,

  • basically what a user would be doing themselves.

  • So how are we going to write some unit tests?

  • And so as we talked about in the last slide,

  • this is testing an individual unit of code,

  • like a function or a class or a method.

  • One great thing about unit tests is they're very, very granular.

  • So you know exactly where your code is breaking.

  • And that makes it very easy to tell what you need to go fix.

  • And so the very most basic unit test is just

  • a function that lets you know when any behavior is unexpected.

  • And so let's go ahead and write our first unit test.

  • So I'm going to make a new directory called testing.

  • And inside that, we're going to go ahead and write our first test.

  • And so let's write a very simple function, maybe something like sum.

  • And what sum does is it's just a function that

  • takes a couple of numbers.

  • Let's do function sum.

  • That takes an x and a y.

  • And let's just return the sum of those two numbers.

  • So return x plus y.

  • So pretty simple.

  • I'm pretty confident that this code does what I think it does.

  • Let's go ahead and write some tests anyway.

  • And so how might we go about doing that?

  • Well, we could write a function that does that.

  • Or we could just do console.assert, which is basically saying,

  • I'm going to assert that this thing is true, and if it's not true,

  • then throw an error.

  • And so let's just assert that sum of 1 and 1 gives us 2.

  • And if it doesn't, then we can throw an error that says error summing 1 and 1.

  • So we can save this and run it using Node.

  • And we get no output, which is a good thing because if there's no error,

  • it means our assert passed.

  • And so let's see what this looks like if we had written

  • assert that doesn't pass.

  • And so say we asserted that 1 and 1 was actually 3.

  • And let me go ahead and quiet this ESLint.

  • So if my now assert that sum of 1 and 1 is 3, then when we run this,

  • we get an assertion error.

  • It says assertion error.

  • Error summing 1 and 1.

  • And so we just effectively wrote our very first test.

  • So let's first fix this and make sure it passes and maybe write a couple

  • other tests.

  • We can do console.assert that summing 0 and 0 gives us 0.

  • And maybe a last one that summing 20 and 30 gives us 50.

  • 20 and 30.

  • And we can just sanity check to make sure this actually works.

  • And it does.

  • Great.

  • So we just wrote our first simple test.

  • And so one thing that you may notice is that we have our tests directly

  • in the same file as our actual function.

  • And so if we were to write something like add with an x and y--

  • or not add, but maybe multiply, now if we want to add a test to this,

  • we're going to have to add some console.asserts.

  • And suddenly, this single file starts to get a little bit noisy.

  • And so just like we've done in other examples,

  • we might want to start breaking out things into separate files.

  • And so maybe the test should not be in the same exact file as the functions.

  • Maybe we should add it to its own test file.

  • And so let's go ahead and do that here.

  • So let's save that, and then create a new file called sum.test.js.

  • And let's just move all of our asserts over to this file.

  • And you may notice that if I try to run that sum.test.js file,

  • it's going to error because sum is not actually defined.

  • And so we're going to have to bring that function called sum

  • from sum.js into its test file.

  • And since we're working in Node, we'll go ahead

  • and use that require statement.

  • So const sum equals require ./sum.js.

  • And then just make sure that in test.js or in sum.js,

  • we need to just make sure that we set our module's exports to be sum.

  • And so this is basically the same way of doing export default in ES6

  • is just the way of writing it in Node, since Node doesn't yet

  • support import and export syntax.

  • So let's just do module.exports equals sum.

  • And then now we can try to do node sum.test.js, and no errors.

  • Great.

  • So what happens if we change sum.js?

  • Maybe we actually add a bug where rather than doing x plus y,

  • we do x plus y plus y.

  • Now if we run our tests, we see that we get an error summing 1 and 1.

  • But it doesn't run the rest of our tests.

  • It just stops at the first error.

  • And so that's a little bit of a downside of the way

  • that we've currently been implementing our tests.

  • And so there are these things called testing frameworks

  • that give you additional benefits.

  • One of them is that they run all of the tests

  • instead of just failing on the first error, like we just saw.

  • Another great thing is it gives you pretty output because currently, we

  • just get this assertion error, which is informative,

  • but it doesn't really look all that great.

  • It also has this cool benefit where it can automatically watch

  • for any changes in our application.

  • So as we change our logic, the test can run automatically

  • without us having to remember to run them before even checking them

  • in or sending them in a new deploy.

  • And lastly, they give you these things called mock functions, which we'll

  • take a look at it in a little bit.

  • So the testing framework that we're going to be looking at this lecture

  • is called Jest.

  • And so if you look up Jest, what you see is

  • this thing called Delightful JavaScript Testing, which is a bold claim.

  • But we'll see that it is pretty great to work with.

  • So this is a testing framework written by our friends at Facebook,

  • so the same people who wrote React Native.

  • And the way to install it is doing npm install --save-dev jest.

  • And so just to do that here, we can do npm install dev jest.

  • So there's a shorthand to just do npm i -d rather than npm install --save-dev.

  • And so this goes ahead and installs Jest.

  • And as it's installing, the way to run it is doing npx jest.

  • Make sure if you want to use the npx command, it's built into NPM 5

  • and above.

  • And I believe can install it otherwise.

  • But in NPM version 5 and above, it's automatically bundled.

  • But the easier way to run it is just by adding a script to your package.json.

  • And so just like in earlier examples, we added something

  • to package.json, which might be, like, linting.

  • We can also add something like test, where we say if we run npm run test,

  • it's just going to run Jest.

  • Jest.

  • And so now we can run npx jest, and we see that it does run.

  • It actually ran our sum.test.js file because it's

  • smart enough to know that anything something.test.js, it should just run.

  • Or we could run npm run test, and it will do the exact same thing.