Flutter Tutorial - Building a Production App From Scratch

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody my name is tatus petra and i run the amateur coder channel where our goal is to explain things so simply that even amateurs can understand it and that's my goal for today's video as well to be able to explain how to build a complete production ready app from scratch as simply as i can so the topics we're going to cover today are planning which in my opinion doesn't get covered enough and i think it's one of the most important parts of building any software some other steps you take before you start building an app building an actual app then there's three types of testing that we're going to cover and finally maintainability and hopefully by the end of this video you'll be able to be confident about the apps that you're releasing to all the app stores i'd like to thank free codecamp for giving me this opportunity and i think all my links will be in the description if you want to check them out and let's get into the video okay so today the app we're building is going to be a very simple to-do app now the code for this app isn't going to be too complex we're going to focus on the process and make sure we go through all the steps necessary to be confident about launching our application and to start with that is planning i think planning is the most overlooked topic when it comes to creating any type of software especially creating an app we're going to focus on two main parts of planning today one of them is requirements and then design so what are requirements it basically breaks down the big requirement of build a to-do app into smaller sections that are more achievable and that you can test at the end so we're gonna have requirements like the following we're gonna have create account be able to login be able to sign up only display not finished to do's keep the list synced up with firebase and lastly if no to-do's say that there's no unfinished dues be able to add a to-do and check off to do's now for each of the topics we're going to get in today there's whole methodologies about how to do them and just like for example requirements there's ways to actually structure the sentences in a way using words like shao and must but today we're going to keep it simple if you're interested in any of these make sure to do more research we just can't cover it within like a couple hours so we got eight requirements for this app now let's get into the design a little bit so with design i like to use adobe xd and there's other options like that you can use but for this one we're just gonna do some very basic drops so we'll have the login screen and then we'll have a login screen so here we're going to have a field for the email the password and then a login button and then a register button nothing too complicated then once inside will have an app bar with a sign out and then add to do and then down here just a list of to-do's you want to kind of get gain a vision for how the app's going to work and make sure all the parts are thought out for example if we didn't think about the sign up button at the top and we wanted to put something else at the top it gets a little clearer up there you just want to think about it now the design doesn't only include how the app looks there's also the architectural design of it so for this app it's pretty simple we're going to have we're going to have the main which will check for authentication and this is not a widget this is just a check then if the authentication data hasn't been received we're going to show a loading screen if there's an error we're going to show an error screen if there's no user logged in we're going to take them to the login screen and then finally if they are logged in we're going to take them to the home screen now inside these two inside the login screen will have a username widget a password widget and then two buttons then on the home screen we're going to have a sign out button and add to do widget and then a list of the to-do's so this is pretty much the way to treat there's software like jaw.i o that you can use but this works for us so that's all the planning we're going to do for this specific app but a more complex app should have days or even weeks of planning in my opinion the things you need to think about are object oriented principles and stuff like that you can look up the principles called solid and grasp those will help you separate the widgets out and keep your architecture clean all right and next is to create some sort of version control and some way to be organized i think almost everybody uses github nowadays so make sure you create a github project and create some tickets and issues in there that you want to work on things like that and then finally we can start on the code so so i'll go do that right now i'll set up a new flutter project and a new firebase project and connect to it okay so we got our firebase project with the email and password sign-in method enabled we're able to run our app once to make sure it works so then i imported these three packages so we could use everything we need with firebase and then also lint along with analysis options.yaml so we can have a static analysis tool that tells us where we can improve our app performance so here you see problems with const we can add that before and now our app will technically be a little bit faster now we got a little bit more preparation before we're ready to start i'm going to set up our folder structure folder structure is very important to make sure you have everything organized and you can access it real quickly so this is the one i use but every project should be a little bit different depending on what it needs so i have a screens folder a models folder a services folder and a global widgets folder or we'll just call it widgets so models are like bits of data that go together for us we're going to use a to-do model which will basically consist of data that is included within every to-do then we have screens we're going to have the login screen on the home screen services we're going to have two services authentication and the database service and then we have global widgets we're only going to have one in there called the to do card which basically will make all our to-do's look the same so now we ready to start not yet there's still some more decisions to make now the final decisions you should think about before starting your app whether you want to do tdd which is test driven development this is actually a really great way to write apps but i personally don't like it too much because i find a little bit boring i like to write a little bit of code and then write the test for it right after then there's the state management decisions for us we're not going to use any state management solutions other than set state because it's such a simple app but state management is a huge topic and will definitely clean up your app architecture a lot so definitely take a look at the top three are provider get x and block so you could take a look at look at each of those and see which one you prefer and now finally i think we're ready to get started so one thing to keep in mind when you're building an app keep things simple and keep them iterative so that means do one small part at a time make sure you check all of it everything works and test it all those things so the first part we're going to start with is getting our connection to firebase working so this part's actually pretty simple there's a new firebase.flutter.dev website that kind of helps you out and this is the initialization code that we're just going to copy and paste right in here so the code in here runs the app you first initialize the app and return a future builder which depends on that initialization so this future builder pretty much takes in the future and builds depending on what state that future is in so if the future has an error we're going to return a scaffold with a center child text error very simple and then you see the blue that's our linter popping up saying we need to fix that then if our connection is done that means it was successful and you can go to your app we're not going to touch that yet and then the last case is it's still loading that if it doesn't have an error and it's not done yet then you know the only option left is loading we're going to return the same thing except we're gonna say loading now the most important part if the connection is done and secure we're ready to move on to our app also one thing to keep in mind we're gonna go through this code a little bit fast because there's a good amount of code in there but we want to mainly focus on the testing aspect of it but i still want to go through the code a little bit so you kind of get like a thought process of how you think through building an app so we have our firebase connected now there's another precondition we need to check whether the user is authenticated or not so we're going to do it inside a root widget which is going to be stateful so you can put this in another file but for simplicity i just put it in here and this is going to send us to our root so root is going to decide where the next page is so now inside our widget we're going to create our firebase auth instance firebase auth i'll call it auth and then firebase auth.instance and then while we're here might as well create a firestore one firebase firestore so then we get into the actual return type i like to use a stream builder for the authentication because anytime anything changes with your authentication state it'll be updated because it's being streamed so the way we do this is we need to give it a stream and our stream is actually not defined here so we're gonna have an auth stream so remember i told you there's gonna be two services that we have one for connecting to the database which is firestore and then one for the authentication so let's do the authentication part we'll have a file called auth.dart and here we'll have a class called auth we're going to pass in a firebase auth instance and does create a constructor for it and we're going to have three functions in here one is going to be a stream of type user which is a type return from firebase now we're gonna get that from auth off state changes so any time the state changes will get returned a user and all the data for it so just like that then we'll have three other functions one's going to be called create account we're going to need to pass an email and a password anything that's related to the future i always make sure to wrap and i try and catch because if anything goes wrong then you it gets caught here here we're not going to actually do anything we're just going to re-throw it back but if you want to create any actions based off of a problem occurring like maybe a snack bar you want to make sure you return whatever you want to return then inside this try catch we're going to have create user with email and password very simple passing the email password and we're actually going to do email.trim just in case they put a space after it then if that's successful we're going to return success and now the reason i made a return a string is because we're going to also do an on firebase auth exception now we're going to catch that as well and return a dot message for that so basically if there's an exception from firebase auth it catches it in this variable e and it'll return a message for you basically why it failed then we can return that from this function give a little snack bar or something telling them that it failed and why so we have two more functions one for signing in and one for signing out i don't think we need to go through that they're going to be pretty much the same all right so that's it that's our three functions that's all we're going to need for the authentication notice how clean this code is all we're going to have to do is call this create account function and everything is going to be handled for us so now in the main we finally have our auth class and remember we need to pass in a parameter called auth and then the string that we're looking for is for the user stream this errors we'll see is because it's not a named parameter and you just do that by adding in brackets to make sure it's named i like to make sure everything is named for myself so we have our stream defined now the builder notice everything's filled out for us we have our context and a snapshot of our current user if our snapshot connection state is equal to connection dot dot active which means our authentication stream is active basically otherwise you want to return another loading state just like that now if it is active we have a couple more conditions to check so snapshot.data and we can look for the uid if the uid is no then we know there's nobody logged in otherwise uid is not null we'll know there's someone logged in so these two screens are going to be real simple so i'll make those real quick and be right back all right so both of those are done they're both very simple the login screen has two text form fields and two razor buttons that don't do anything just now and the home screen just has an app bar so here if the snow return login with an authentication of auth and a firestore of firestore now we're doing a lot of passing authentication and firestore everywhere this is why i think you should use some sort of state management because you only need to pass those around everywhere but it's not too bad for us then over here we're going to return the home screen and we're going to need an auth of auth again and firestore of firestore now within to do widget we have the two functions for signing in and create an account all we do here is call those functions we created so this will return a success or the error message if you remember we're gonna need to do auth and sign in the user with email from the email controller and password from the password controller dot text then we can check if the return value is equal to success then we can clear those controllers otherwise let's display a snack bar with the return value because remember we'll return the error okay copy paste that and add it here obviously it'd be nice to have another function like this but i think since it's such a small piece of code it's okay and we only do it twice so not too bad long screen should be done and i think we can run the app at this point and see if it works or not and of course things can't work on the first try like that but it's actually pretty simple we never wrapped it in a material app or anything so make sure this future builder is wrapped in a material app and then this should be the home and we might as well add some theme and make it dark theme because you know we're programmers that's that's kind of what we stick to and there we go let's see if it's working so we create a username let's just type anything signed in password is invalid and the user does not have a password or the user does not have a password okay so let's try tatis gmail.com password one two three four five six sign in there's no user record correspondence identifier user may have been deleted okay then let's create an account first we created an account and there we go we're back in the home screen now last part before we start testing is let's actually create do something when we try to sign out so here we need an auth again we have our authentication pass to this and we can just do sign out easy and now hopefully we click it and we'll go back to the main screen now we're able to type in our email again and this time we're able we're not able to create an account just email our address is already in use but we're able to sign in there we go that's our full complete login process now after this stage is where the testing begins so the nice thing about test driven development or tdd is that at this point you're pretty much done you know your app is fully tested and that everything works but for us we don't have that yet so we're gonna add some unit tests so what unit tests are they basically test the unit per se so a unit is just a function pretty much and the only things that really make sense to test in this application are these functions that we have create account sign in and sign out you also want to make be careful about not writing useless tests you don't need to write a test for every little simple thing you do in fact there's probably an argument that these don't really need to be tested since firebase already tests this for you and you're not really you're not really testing much but just for demonstration we're going to go through it so the reason i wanted to go over is because these tests could be a little bit more complicated given that they need mocks in them so we're going to need to add some more dependencies in here we're going to add mokito and then we're also going to add flutter driver and test but those are for the integration test for this one we only need moquito and flutter test so each of your tests needs a main and then inside your again you can have a setup and a tear down so what these are the setup runs before every single test and the tear down runs after every single test then checking back to this class what was the one thing i said we're going to need this firebase auth in order to do anything we need this authentication but for us we're going to be mocking it so it's not calling the actual database so like i said the thing we need to mock is the authentication class so we will create a mock auth class the way you mark it is you need to extend that class with with a mock you'll see we have a library imported the mokito library and then it implements our firebase auth class so basically this says we're mocking our firebase auth class and this is the class that will contain all the mocks so once we have our class defined we can create an instance of it and now we will be able to use this for all our tests so our first test we're going to call emit occurs so we're going to test that this off state changes actually emits and we get a user from it we do that by overwriting the function up here so auth state changes you just type it out i'll send you this whole thing and what we'll need to use is a stream dot from iterable now inside here we're going to iterate over the type of objects that you use so you saw this should return our user so we're going to do is create a mock user as well so we'll have mock user extends mock implements user and then here we can return a mock user so before we get to the actual test case i want to change this name to mock firebase auth just to make sure we're all clear that this is the firebase authentication our our class is actually called mock as well so we're not mocking this class we're mocking the firebase auth that we're passing in so now we can create our instance of our auth class as well and remember we have to pass in an authentication and that authentication is going to be mock firebase auth so there now we have our auth class that we can use for all our tests so here we want to call expect later which is for anything with futures and we're expecting the auth user class to return a stream which we can check by emits in order and inside here we'll have the mock user so there we go now if we run it well you'll actually see a problem there so we're expecting an emit of the type mock user instead we got an instance of generated stream of just user so what happened here well in flutter if you have two instances of an object let's say you do this simple check if you do mock user is equal to mock user even though they are exactly the same this will always return false this is because a separate instance of a mock user is not equal to a different instance there are packages like equatable and other ones i'm pretty sure that actually check the properties within i tell you whether they're equal or not but since we're not using that we have another option you can create a variable for mock user and then use the same instance within this iterable and this emit check so now if we save and run everything passes great so we got the mission there now go back to this function and we need to check this first part whether create an account works so you can copy paste that and check create account so here the difference is we want to mock an actual call to database so we want to mock this create user with email and password we're not trying to override it like we did here we're trying to catch it and then return something of our own instead of the database so you will need to do when and then inside basically do when the mock mock firebase auth dot create user with email and password gets called with the fields we'll say tatusa gmail.com and password one two three four five six so when that happens then answer and we put in whatever value we wanted to answer with so actually in this case we don't really care where it answers it will just return success no matter what the answer is unless it throws an exception that's the only way it doesn't return a success and it will throw an exception if this wasn't successful basically so we mark it we don't really care what the return is and then we can do and expect where we await our auth class create account and we want if we don't pass anything that means these aren't going to get called to the specific fields that we mentioned here so we want to make sure we pass the email of todas gmail.com and password of one two three four five six now since it gets called with those exact fields it will return with a success okay let's try to run it perfect it works now we could check the same thing except for this firebase auth exception make sure the exceptions actually work create account exception so when this function gets called instead of turning null let's actually throw a firebase auth exception and you can put your own message like you screwed up now we can actually copy this message and that should be our return for that function now we can run all three actually to check all of them pass perfect now i'm going to copy paste these and we'll do for sign in i will do sign in with email password pass those in sign in that should run sign in exception you do sign in with email password sign in function gets called perfect now we should be able to run those that one runs this one runs and then we could do the same thing with sign out these don't need any calls let's check how this function works so success if it's no and same thing with exception very easy sign out and there we go now we can run all of these tests and we have one two three four five six seven eight tests that all pass let's say firebase gets updated or something and the signed out function works differently our tests will not pass anymore and now we have full coverage for all of our authentication functions and let's say firebase updates they no longer throw a firebase auth exception they throw something else then one of our tests is going to fail when we run it because we only catch a firebase auth exception we don't catch the other ones so our code is more safe and you'll be able to catch problems with anything you interface with and you'll know that it's not your app that's actually broken into something else so that's it now there's another type of testing called widget testing widget basically tests your ui the thing is we don't really have anything that's driven with the ui here we just have a sign in screen that is based off of the firebase database it's not really ui changes right so we'll come back to that and the integration tests after we do the to-do lists so for this next part we're just going to go through the database interfaces because the rest is just making ui to work with it and i don't think that brings too much value for you guys so we're going to need a to do model and here we're going to have a to do model class with a to do id the content of the to do and then whether it's finished or not then we're also going to give it a name constructor from document snapshot going to want to pass in a document snapshot for it then in here just simply set the to-do id equals document snapshot dot id content equals document snapshot.data content as string and then same thing for the done except as boolean okay so now our database class we're gonna need to pass in firebase firestore and the constructor for that and then we're going to have a stream of the list of to do's that we have so stream of list of to do model i'm going to call that function stream to do's and all we need is the uid of the user so the way our database is going to work we're going to have a collection called to do's then have a document with the uid and then within that uid we're gonna have the to do is for that specific user and then we're gonna have the to-do id content and done so that's what our databases are going to look like very simple and easy to use so for the stream you want to again try catch as always and we will try to return firestore that collection remember to do's collection that document of the uid we passed in and then that collection of to do's and we only want to get the ones where the done field is equal to false and then we want the snapshots of that so that returns a stream but we want a stream of list of to-do models so we gotta map it to such a list these snapshots will return a query for us and then i like to space it out even more we will have a list of to do models that we want to return at the end we've got to make sure to return that and then here we're going to have a for loop for each document in query dot docs so all the documents that that query returns we're going to iterate through every single one and then append to the list we have with a to-do model from document snapshot and a pass in that document okay that was a mouthful but it's not as bad as it looks so we return a query and then we go through every document of that query add it to this list then return that list through a stream that's pretty much it so then we have two more functions i'm just i'm just going to go over them with you there's not too much to them this one's to add a to do if you remember we need the id and what the content of it is so we'll find the collection name to do's go to that specific uid go to the collection call to do's again and add a document with the content and the done field is false then we want to update that to do so we'll have the uid and then the to-do id so we're able to get to the specific to do item and we just update the done to true so i'll go ahead and make the ui and use this and then i'll be right back okay so here we have the home screen we have list app we can call it amateur coder to do instead nice so i have our sign on at the top we have a text saying add to do here a text form field an icon button which calls our add to do function that we created and then a list of your to-do's inside of a stream builder which takes in the stream to-do's that we created and then similar to when we log in we have a snapshot if it's active and our data is empty means we don't have any to use want to return you don't have any unfinished to do's and if we do we have a list built list view builder which returns a list of to do cards and to do cards are just a card with an expanded text and a check box next to it and if we click on the check inside the check box it will update our to do to be checked so let's see if it works for the fun of it go eat a hot dog we can add that go get a hot dog perfect if we refresh here showed up uid and then to do and here we go and the cool thing is if we update here you'll see it update right there right away and same thing we got a check box we click it it's gone from here that's turned to true and you're good to go if you want to implement another screen saying to do is that we're finished you can take this code and do it it's in the description but now to test it so remember the fact that i told you about there's no need to have useless tests all these things in firestore are already tested so writing tests for these doesn't give us much value actually so we're going to skip the unit test for this if you want to do it it's very similar to the way we did the authentication tests so you can try that on your own so the thing with flutter is there's two more different types of tests there's widget tests and then there's integration tests now what widget tests are is they test how your ui reacts if you click or touch something so basically it's ui tests the thing about our app that we created is there's nothing driven by the actual ui everything is streamed so when you click this button you're not doing anything within the page you're actually just sending it to firestore and then unrelatedly the stream builder updates once the firestore data comes in so there's nothing really to widget test here but i still wanted to show you how widget tests work and i have a to do app that doesn't use a database so let's look into that okay so this is the to-do app it looks pretty similar right except there's one big difference we have a controller and this list isn't being streamed from firebase or anything it's just a static list that we're holding in the app as well the database isn't actually a database it's just a future that returns from database and true so if we look at the app you can add things like hello add it and then load to do from database you load it in from database and it's checked but if we reload it it's all gone anyways this means it's ui driven now this button when we click it actually does something within our app before the button click sends it to the server and then comes back right so here we have some widget tests we're just going to go over them because i think widget tests have a lot of material online i think integration and unit tests are the ones that are a little bit less covered and if you want more information about widget test unit test and integration test i have videos more dedicated to that topic on my channel so make sure to check those out but we're going to read through this simple widget test that i have so this test is called add a to do and remove it and you'll see we have this tester.pump widget so it's pump widget basically means in its ram or in its memory it brings that widget up in the background like we don't need to we don't need to be running this and this test will work some background it launches this widget we wrap it in a material app because you need a material app to launch anything or at least use the scaffold then we launch our home screen then we have these add field and add button they have a value key on them so if you go back to our home screen you can add things called keys to the buttons and form fields and that makes it a lot easier to find them with our widget test you can also do find by type by type what type of widget it is by tool tip things like that there's more than more than just that way to find stuff and also we'll have find dot text get groceries so this basically looks through everything in the widget tree and see if there's a text called get groceries so now for the actual widget tests we use the widget tester the same one we use to pump the home widget so we bring the widget basically onto the screen we enter the text get groceries into the ad field we tap the add button and then we call this pump function which rebuilds just basically like set state does and then we can expect to find a get groceries so message finder basically tries to find a text called get groceries and we tell it that it should only find one of them so we can run this now and it passes let's say we do finds nothing it doesn't find any widgets so basically we add a text field and we're expecting it not to show up we have a problem right there said it actually did find that so that's all we're going to cover for widget tests there's a lot more documentation on the flutter docs you can watch come to my channel check out the videos if you need some more help but it's not too complex the most complex one in my opinion is the integration testing okay so we covered unit tests which go over the function then we cover the widget test which goes over a whole widget and now the last one is integration test and that goes over the app as a whole but to do that you need to run the app there's no way you can really test the app as a whole without running it if you remember we added this flutter driver so this flutter driver is the one that pretty much does the driving of the integration tests so we're going to do is add another folder called test underscore driver and here we're going to need two files we're going to need a app dot dart and we're going to need a app underscore test.dart inside the app dot dot we're just going to copy the flutter documentation and this basically runs the main of our app call the main function of the app or call run app with any widget you are interested in testing so then for the actual app test we're going to go to the documentation again and copy the the code that they have okay now let's read through this so this imports the flutter driver api all good we have all the finders that we have just like we checked in the widget test except there's a by value key so it's a little different syntax but similar idea then in the setup we want to connect to the flutter driver and then close it whenever we tear down and then they have two tests here we can remove these tests we don't need them our first test will be create account we're actually going to have three tests total so you can just put them in here already we'll have a create account we'll have a login and then we'll have add a to do so notice we're doing creating the account that means it has to call the firebase server right and that's perfectly fine with integration tests you can do that it actually builds the whole app with the firebase connected to it and you can actually run the tests but i would recommend doing this not on the production server and have a different firebase project that you connect when you do testing so what i'm going to do right now is i'm going to go through the whole app and add a bunch of these value keys because we need to use them so on the login we have the value key called username and we can make a constant and i'll be back when i do this with every widget that we're going to need to use okay so these are all the objects that we're going to be using in our integration test we have the username password sign in create account sign out button add field add button so now in the create account first i want to check if there is a sign out button present because this builds the app and launches it if our authentication is already there we're going to be already logged in this test is going to fail because we're already logged in with an account so there's this function i made called is present basically it looks for the value key and it waits for a certain timeout that we pass in which one second if it doesn't find it within one second it'll throw an exception we return false if it does find it within one second it will continue and we will say that it is present so pretty simple so we check if our sign out button is present then we want to await driver which is what drives the actual test and we want to tap on the sign out button so we'll check if it's there if it is sign out once that's done we're going to await driver like i said this thing basically does everything for you within the app you want to first tap on the username field just like you would use the app you have to tap there first in order to type right now i can copy it and enter text and here we'll enter let's say tatus1 gmail.com taught us that gmail is already taken so we get an error in this case obviously i don't know if this create an account test is worth making since this is testing whether firebase works or not but we're just doing it for demonstration purposes hopefully you will learn something so then let's tap the password field enter the password very secure one two three four five six and then we finally tap the create account button so that should have done the test for us now what do we do next we just wait for find the text called your to-dos if you remember on the home screen there was added to do and then there was your to-do so we find the text we know this worked and now this integration test is done and we can run it so the way you run the test is you do flutter drive target and you put the test driver app.dart that we made over here as the target so this will enable the flutter driver extension then run your app and then run your tests so if we click it let's see what happens so i was in the wrong directory but then i got to the right one and here's us running the flutter driver and then there's multiple devices found i have an iphone connected an ipad and then this is the iphone 11 pro so we want two so there we go it's done and now it's launching it'll start off logged in i think it's logged in logged out you saw that got pressed and everything worked all your tests passed and now if we check firebase taught us one gmail.com so there we go that's how integration tests work now let's quickly add these last two we'll pretty much copy this one if it's present sign out if it's not enter the password and then instead of create account button let's do sign in button then add a to-do want to check if it is signed in already just because we don't want to do be doing to-do's while we're in the login screen if it is tap the add field which is this part enter the text make a video for free code camp then tap the add button and then let's wait for the text make a video for free code camp to show up also you can add your own timeout in here if you want let's stay say three seconds make that constant again and now let's remove this tata swan at gmail so get that problem again and we can run our integration test again it's running you see logged in logged out log back in and created us to do for make a video for free code camp nice that was pretty cool i wish you could slow it down a bit so there we go we have created a pretty robust to-do list app uh it has unit tests it has integration tests doesn't have any widget test but if there was anything ui driven would have definitely done it there's also one more type of testing called functional testing this is pretty manual so i didn't really go over that but you also want to make sure you play around with your app by yourself make sure the ui looks good like for example all our tests would have still passed if this to do screen right here if this to do was off the screen it would have still worked because it's technically within the widget so you want to make sure everything looks good as well and the animations behave as as you want things like that now the last point i wanted to go over was maintainability things you should keep in mind as you work on this project because i'm sure you made a to-do app there's a lot of updates i want to push to this right to make it even better so one thing one great thing for maintainability is to set up a ci cd pipeline cicd stands for continuous integration and continuous deployment or delivery i don't know i've seen both basically this gives you the ability to set up a pipeline where you push your changes to the master and then it runs a test for you it builds the code it checks everything and deploys the app store all automatically i think it's very useful and makes it more reliable that like your release will happen the same exact way every time i have a video about this on my channel if you want to check it out it's for code magic with flutter it seems to be the go to cicd platform for flutter another big thing is to make sure you keep up with your tests as you go because i know even if you do it at the beginning it's hard to always keep up with them but they will definitely save you time in the future when you have updates make sure you break it down in github keep it organized make sure you break it down into simple tasks because you want to make sure you incrementally change and everything works incrementally this way you can track where things go wrong and make sure they don't go wrong i guess in the first place and then as you keep building up to it if you keep your architecture principles in check and keep your testing up to date you will be a lot more confident about your app and you'll be able to release the app store with less bugs and people will enjoy the user experience a lot more and as you go forward i'd make sure you go through the whole process we went through today for every change make sure you check the requirements go through the design the widget tree planning all that stuff uh it might be a little bit tedious but for smaller changes it won't shouldn't be that bad and i'll definitely make your process a lot more smoother so that's been it for me once again i'd like to thank free code camp for giving me this opportunity if you want any more in-depth details about any of the topics we covered make sure to come to my channel i have videos on almost all these i think this code will be in the description and i'll also add the code for the widget testing as well and that's it for me thank you for watching
Info
Channel: freeCodeCamp.org
Views: 126,212
Rating: 4.9075146 out of 5
Keywords:
Id: aiTTClKJbnw
Channel Id: undefined
Length: 53min 20sec (3200 seconds)
Published: Tue Sep 22 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.