Turn Prototypes into Robust Software with MATLAB
Overview
MATLAB is known as a great environment for experimentation and rapid prototyping. But once you've got your code working, important decisions may start to depend on it. How well have you tested it? Can others understand it? Is your code really ready for more?
In this session, we'll introduce several key concepts and tools for turning rapidly developed code into robust, sustainable programs in MATLAB. These techniques will be useful to MATLAB users of all experience levels who are interested in creating more maintainable and reliable programs.
Highlights
- Getting organized with MATLAB Projects
- Managing changes and collaboration with source control
- Testing your MATLAB code with unit testing
- Automating software workflows with the MATLAB build tool
About the Presenter
Adam Filion is a Principal Product Marketing Manager at MathWorks where he focuses on building demonstration and teaching materials for the MATLAB platform. You can also find him teaching the Practical Data Science with MATLAB specialization on Coursera and in many other MathWorks videos. He has a BS and MS in Aerospace Engineering from Virginia Tech.
Published: 25 Nov 2024
Hello, everyone, and welcome to today's webinar on turning prototypes into robust programs with MATLAB. My name is Adam Filion, and I'm a principal product marketing manager here at MathWorks, which means I spend most of my time building teaching and demonstration materials to help people learn MATLAB, like you're going to see today.
In today's presentation, I'm going to cover several different tools and techniques to help you robust and reliable programs that your business can depend on. This topic is very deep with much more to it than we can cover today. So my hope is that today's presentation is just the start of a much longer conversation about how you can better software in MATLAB.
And we're all here today, really, because MATLAB is a great environment for rapid prototyping. It's a place where you can get an idea and just immediately jump in and start coding, trying things out, evaluating alternatives, failing and trying again, and iterating until you get something that works or at least looks like it works.
And I'm going to call the output of this workflow your prototype. Your prototype could take one of many different forms. It might just be a simple script. It could be a MATLAB app. It might be a compiled library of some kind. But whatever its form, this type of workflow is what made MATLAB so popular in the first place.
But now that we have this prototype, if we were to peel back the surface and look at the code underneath, what does it look like? Well, if you're anything like me, the code behind your prototype is a big, messy, labyrinthine pile of code that nobody else, and maybe not even yourself, can understand. Maybe it's a single script that's hundreds of lines long. Maybe none of it is well commented. Maybe none of it has been tested.
But whatever its state you need to ask yourself, is your code ready for important things to depend upon it? Now, this can raise a lot of concerns you may not have thought about as you were creating your prototype. Things like, is it robust to unexpected errors? Is it going to be fast enough to meet your users' needs?
How are you going to collaborate with other developers? And how are you going to take this and package it up and deploy it to endusers? So a natural question I always get at this point is, well, where do I start? And the full answer is always it depends. It depends on the goals of your project. It depends on the current state of your prototype.
And it depends on your skill set and what you are comfortable doing yourself. However, our consultants have done many, many projects on exactly this topic, helping our customers turn their rapidly built prototypes into software they can depend on. And they have found three topics really stand out as being critically important for basically everyone.
So I can pretty much guarantee, even without knowing the details of your project, that focusing on these three things is going to be a really good use of your time. And the first and most important is automated testing. Not a big surprise that if you want software you can depend on, you need to be testing that software. And you don't want to have a bunch of manual tests where you need to manually remember what you need to do and then point and click on a bunch of stuff.
You want automated tests so that testing is fast and easy and repeatable. So we're going to introduce some ideas and tools for automated software testing in MATLAB. The second most important topic is Source Control and that you're following best practices. So we're going to introduce the basics of using Source Control in MATLAB today. And then the third most important topic is how you are organizing and architecting your software.
So we're going to introduce a few ideas from here as well. Each of these topics is a very deep field of study in and of itself. We could easily spend the entire hour today just on one of these topics and still not get to everything. However, at the same time, each of these is relatively easy to get started with.
So I'm going to introduce just a couple of the basic ideas and tools to get you pointed in the right direction. And whenever you are ready to learn more and go deeper, we have a lot of information available on our website. And, of course, you can always reach out to us directly. We're always happy to talk one on one.
Now, another common question I get at this point is this feels like a lot of work, and my code works for me. So what's the big benefit of doing this? Well, we're going to illustrate that with an example where we're going to improve an existing project. We're not really going to worry about the details of the application. But just so you know generally what it is, we're trying to forecast electricity demand in the state of New York.
And our starting point is going to be a flat folder of files where we have a live script that demonstrates our idea. So this is really kind of our prototype. But then the script also has half a dozen helper functions and some reference data saved to MAT-Files. So to get a better understanding of the benefits of today's topics, at this point, we're going to hop over to MATLAB and take a sneak peek at the endpoint of today's demonstration.
OK, so here we are in MATLAB, and we're going to start over here in our current folder. As you can see, we've got a collection of folders and MATLAB files. And I want you to imagine that you are looking at something for the first time, as you are right now, or you've come back to a project you haven't seen in a while and maybe you don't remember how it's all supposed to work. One of the first challenges is knowing where to start.
And one of the topics we're going to introduce today is something called MATLAB Projects. And any time you see a Project or PRJ file, that's always a good place to start. If we open that up, we'll see it's going to do a few things for us. The first thing it does is it opens up a new window that looks kind of like our current folder, but now it's only showing us the files that are relevant for this project.
And you can see from the color coding on these folders that it's also managing our path for us. And this is the first big benefit of using MATLAB Projects is path management. If you've used MATLAB for any length of time, you've probably run into some kind of issue or error because of your path at some point.
MATLAB Projects will automatically set your path upon opening them and then restore the path's previous state upon closing. And this is really powerful, especially when you have multiple different projects that you move between and each has its own unique path requirements. The second thing it did is it opened our prototype for us. And this is an example of the second big benefit of using MATLAB Projects.
They can manage your startup and shutdown activities. So if there's something you always want to do every time you start working on a project like opening your prototype, you can have MATLAB Projects just automatically do that for you. And they can also do shutdown activities when you close them. And these activities can be anything you script in the MATLAB language.
Years ago, I had a colleague, and every time he created a collection of MATLAB files, there was always a script called run me first. And you had to manually remember to go run that script first or none of the rest of his code would work. These days, that all gets automated away with Projects. So Projects, between setting your path and the startup and shutdown activities, these are great for creating reproducible environments so everybody always knows they're starting from the right place.
But now that we've got it open, the next thing I always like to do is try to understand what's the structure of this project. And for that, I'm going to come up to a tool called the Dependency Analyzer. And the Dependency Analyzer is going to look at the files in this project, and it's going to try to put them into a graph. And I'm going to color code them by the type of file here.
And we can see that our main prototype script calls five of the different functions in this project. And then some of those functions call other functions or MAT-files. And there's a number of tools here in the Dependency Analyzer to help you understand what is kind of the structure of the files in this project and how do they relate to each other. So this is a place I often go to get a quick sense for how are things being organized and used.
The next thing I often look for is, well, how is this project changing over time? And who is making contributions to it? And this is where Source Control comes in. We mentioned Source Control briefly earlier, and MATLAB Projects integrate very well with Source Control environments. If you're tracking things through Source Control, we can easily get a list of all of the changes that have happened over time for this project.
And in this little demo project, we can see a collection of five of them. We can see for each change who was the author. So who made this change? And what's their contact info in case we want to reach out with questions? When did they make the change? Why did they make it? And exactly what did they change? And we can actually drill down here to see the line by line code changes.
So this gives us a fast and easy way to figure out how is this changing over time and who should I reach out to if I have questions about some of these changes. So that gives me a better sense of how is this organized and how is it changing. But what can I actually do with this project?
Well, you can see one of the files we have here is something called a build file. And a build file is just a function file that defines all of the different sort of big tasks related to this software and our workflow with it. If we have a build file, we can leverage it from the command line using something called Build Tool.
And here, I'm going to ask Build Tool to list out what are the various tasks associated with this project. And we can see this little project has three. There's an archive task to turn it all into a zip file, a check task to look for code issues using the MATLAB Code Analyzer, and a test task to run the software tests that have been written. And if we're coming across this project for the first time and we're interested in using it, well, we probably want to make sure that those tests are running first.
So using the Build Tool, we can tell it to go run the test task. And it's going to take a moment to start that up, look for any tests. There's two implemented for this project and they're both passing. And this is really important information to know before we try to pick this project up and use it. So as we've seen here, we can very quickly figure out what this project is and how to use it.
Thanks to MATLAB Projects, we can create a reproducible environment, set our path to our startup activities. We can use things like the Dependency Analyzer to figure out what is the overall structure of this project. We can use Source Control to track changes and see how it's changing. And we can use the Build Tool to see what are the major tasks here and do things like run software tests.
And we can do all of this without needing any prior knowledge of what this MATLAB project is or what it's supposed to do. Now, I want you to think about what if everything you did in MATLAB had this type of tooling and ecosystem built around it. And I think you'll start to appreciate the benefits of the techniques we're going to talk about today.
But with that, let's hop back over to our slides and go a little more in depth on the first topic for today. So this is going to be our agenda for today. A few slides ago, I laid out these three topics in a different order. We're going to go through them in this order today simply because for our particular demo, I found this was the easiest order in which to adopt them and add them to the project.
There is no correct universal order. And the best order for you to adopt things might be a little different depending on the details of your project. But we're going to start by talking about the organization and architecture of our software. And there's kind of two main subfields to think about here. How are you organizing your files versus how are you architecting your algorithms in your code.
When it comes to file organization, this is all about answering questions like is your code base understandable? Is its organization obvious? Is it easy to find things and is it clear how to get started? Or to put it another way, if somebody new stumbles across it, can they figure out how to use it or are they going to be totally lost?
This is a place where the pain is often felt as the code grows. And the bigger and more complex it gets, the more painful this becomes. The good news is there is some general advice that is applicable to almost everyone. And your file organization is something that's relatively easy to plan and also relatively easy to change later.
Now, this contrasts with your algorithm architecture. So this has to deal with things like should you be writing this as a script or a function or a class. And it gets into a lot of terms and ideas that you might not have heard of before if you don't have a background in software development or software engineering-- things like the single responsibility principle, separation of concerns, encapsulation, and a number of other ideas.
This is also a place where the pain is often felt as your code grows. When your code is very small, you don't have to think very hard about this. But as it gets very large and complex, this can become a very important topic. And unfortunately, unlike file organization, when it comes to your algorithm architecture, there isn't a lot of general advice that works for basically everyone. The right architecture really depends on the details of your application.
And to make matters even more challenging, this can be tough to plan. But it's even more expensive to change it later, which means whenever it's time to sit down and try to get your architecture right, there's a big incentive to try to get it right the first time. So for these reasons and since we don't have a lot of time today, we're going to focus on the generally applicable advice that basically all of you can use around file organization. And we're going to leave a more detailed discussion of algorithm architecture for a different day and a different presentation.
Now, I always encourage people to start by getting organized because poor code organization makes a project hard to learn and use. So here, we've got a kind of a flat directory of MATLAB files. And again, if you've used MATLAB for any length of time, I'm sure you've seen something like this before.
And whenever I do, my eyes just kind of glaze over because I have no idea where to start. I have no idea what this thing is supposed to do. I have to read through all the file names to try to figure that out. There's no getting-started guide and there's no indication of what I, the enduser, need.
For example, there's two Excel files here. Do I need those? Or are those just there for the developer to test the functionality? I have no idea. So it's a good idea to pick a general standard for how to organize your various projects. And one good choice is the MATLAB Toolbox model.
MathWorks maintains on its GitHub page a list of best practices for organizing your own code, like a MATLAB Toolbox. And if you scroll down and look at the table of contents, you'll find some basic stuff like how to organize your root folder, but also extensions for incorporating software tests, getting organized with projects, integrating with source control, and automating with the Build Tool.
And this is one of the reasons I recommend this standard because it incorporates all of the topics we're going to talk about today. This is one simple example of what a Toolbox layout can look like. To start with, all of the shareable code goes into a Toolbox folder. This is all of the code that the endusers of your program need to have and consume.
Inside of it, its organization might be a little different depending on your project. But in general, there's folders for things like code and data and, of course, a clear getting-started guide. This is great not only for new users, but also for yourself when you come back a few months later and have forgotten how this is all supposed to work.
Then outside of the Toolbox folder is everything the developers of the application need, but the users don't, such as a project overview and a readme file but also things like software tests and a build file and maybe a license if applicable. This is just one example. Your layout can be as simple or complex as you need.
Some other things to think about is things like generated artifacts if you're creating nex files, any custom documentation that you want to package with it, as well as non-MATLAB code. And how are you going to organize that if your application is not written purely in MATLAB? Now, as soon as I showed nested directories, I know some of you immediately thought about the path.
We've already talked about that a little bit today. Doesn't all of this organization make the path harder to manage? Yes, it absolutely does, which is why you should be using MATLAB Projects to create reproducible environments. As we saw a little earlier, Projects track all of the relevant files so you always know if you have everything you're supposed to have or if you're missing something.
And they do two big things for you. They manage your path, automatically setting it on startup and resetting it on shutdown. And then you can have any customized startup and shutdown activities you want. Anything you can script in the MATLAB language, you can automate.
They also have tools for simplifying common workflows like Source Control integration and then a number of advanced tools that we're not going to have time to get into today for things like refactoring code, renaming things throughout a project, assigning metadata labels to files and grouping and filtering by those, and also creating reference projects, which are reusable projects other people can build on top of without needing to copy-paste a bunch of files all over the place.
So with that, let's go ahead and hop back to MATLAB and see how from the very beginning, we can start to get organized. So once again, looking at the current folder window, I've taken our flat directory of files and I've already put it into the Toolbox folder model. This just involves creating some folders and dragging and dropping some files. I'm going to assume you all already how to do that.
So once we get things organized into folders, we then want to turn this into a MATLAB project. And to do that, we can go up to the New option in our tool strip and then go to Project. And you can see there's a few options. And note that some of them are to create a project directly from Source Control.
So as I mentioned earlier, I'm going to adopt these techniques in a particular order today just because I found them easier for this particular example. But there's no correct order. And if you find it easier to go through this in a different order, or if you already have things in Source Control, you can create a MATLAB project directly from that Source Control repository.
But for us, I'm going to create a new project from our current folder. Going to give it a name-- I'm just going to call it Demo project. And it's going to prompt me to do the two big things we've talked about-- set our paths and our start up activities. So I'm going to add the Toolbox folder with all of its subfolders to the path.
So every time I open the project, everything under Toolbox is going to get added to the path. And then we can define any startup and shutdown activities, as well as make some environment variable changes. I don't have any of these today, but we can always come back and modify this later. And there we go.
And that's actually everything that it takes to get your files organized in the MATLAB Toolbox model. Just create some folders and drag and drop, and then you can very easily turn that into a MATLAB project to start automating your path management and any startup and shutdown activities you have. So with that, there is, of course, more advanced functionality inside of Projects that we could get into.
But for today, we're going to go ahead and hop back to Slides onto our next topic, which is going to be Source Control. So you need a good way to track changes to your code. And when I was back in grad school, this was my way. It looked exactly like this, including both a final and final final folder because trust me, this time I mean it.
But if you want to be successful in building complex software, you need a better way to track changes. And that better way is Source Control. Source Control is a system for managing changes to your code and other artifacts. It gives you the ability to track those changes and figure out who changed what.
You can make backups on remote repositories that maintain your history and give you the ability to restore previous state, has a lot of nice tools for reconciling conflicting changes. So if I change one part of the code and my colleague changes the same part of the code, how do we reconcile that? These remote repositories also give you a great way to share what you're doing and collaborate with others.
And last but not least, it can save you from yourself. And this is actually one of the biggest reasons that I use it. I'm sure we've all had those moments before where our code is working. And then we make a change, and it breaks. And then we can't seem to get it back to the way it used to work.
Well, if you're tracking things through Source Control, you can always revert back to a prior state where it worked the way that you remember. It's kind of like having an infinite undo button. As you're using Source Control, it's going to track all of the relevant details for changes to your code base. There's a number of different ways of looking at Source Control information in MATLAB.
You saw one view earlier inside of MATLAB. This is another example, but they're all kind of similar. We get a table of changes over time with the most recent at the top. And focusing on the most important parts, it'll tell you who made each change, when did they make it, why did they make it and what is the reason they gave, and what exactly changed. And we see in this particular commit, only one file changed. And we can drill down to the line-by-line code changes if we want.
When it comes to interfacing with Source Control, MATLAB gives you a couple of different options. So one is the Current Folder Right-click Context menu. So if you right-click inside of the current folder, there's a Source Control option in the dropdown menu. And this has been there for many, many years now. If you're using MATLAB Projects, as we've already seen, they integrate very nicely with Source Control. And you can use it directly through the Projects tool strip.
And while almost everything we're talking about today has actually been in MATLAB for many years, one of the newer features is in the 23b release. We added a new Git API so you can script Source Control actions with Git directly in the MATLAB language. So all of these different options for interfacing with Source Control, they all work well. Use whichever one makes the most sense to you.
Now, there's a lot of different methodologies and philosophies around how to use Source Control. Like all of the topics today, we could easily spend the whole hour talking about nothing but Source Control. So for the sake of time, I'm just going to quickly introduce a very basic way to start using Source Control on your local machine.
So the first thing you would need to do is take an existing folder and create what's called a repository. A repository is just a collection of files that you're tracking inside of Source Control. And if you have multiple different things that you're working on, you're going to have a different repository for each one of those things.
Once you create a repository, you need to add the files that are going to be a part of it and you want to track. By default, Source Control doesn't assume that you want to track anything. Then we need to perform what's called a commit. A commit tells the Source Control system to take a snapshot of whatever your current state is and remember it.
Then as we go along and we edit our files or we create new ones-- every time we make a change, and we want to keep it-- we're going to do another commit operation to snapshot those changes. It's important to remember Source Control doesn't care about saving files. It only cares when you do a manual commit operation, telling it to take a snapshot.
And as you're working, you want to make small, frequent commits as you develop your code. One of the most powerful parts of Source Control is the ability to pick apart changes that have been made over time and revert or undo some of them. But that's only easy to do one commit at a time.
So something you want to avoid is going days or weeks without making any commits and then do one big commit with a whole bunch of different changes all at once. That's a bad way to do things. You want to make small, frequent commits as you work. And as you're making those small frequent commits, you want to make sure to write descriptive messages to go along with them.
As this example reminds us, these first two messages-- these are pretty good, letting us know that we created the main loop and enabled config file parsing. However, things like miscellaneous bug fixes and code edits, those don't really tell us anything useful and the rest of these messages are even less helpful. Now, this is just one very simple way to get started on your local machine.
There's a lot of other powerful things you can do with Source Control that we, unfortunately, don't have time to really dig into today. Remote repositories are one of the most powerful. They allow you to back up everything that you're doing in a remote location on some kind of a server like GitHub or GitLab and also to share what you're doing with other people and collaborate.
You can use what are called branches to separate the experimental in-progress work you're doing from the well-tested, ready-to-share materials for other people to use. And you can prevent accidental changes to those ready-to-share materials through things called merge requests. You can also reference other repositories through things called submodules so you aren't copy-pasting files around all over the place.
These are just a few of the most important topics to go look into after today if you want to learn more. But for now, we're going to tab back to MATLAB. And we're going to see how we can get started just doing some simple things with Source Control on our local machine.
OK, so as we talked about in Slides, there are a number of different ways to interface with Source Control in MATLAB. They all work well. But since we have our project open already, I'm just going to go to this Use Source Control button.
Now, if you created this project directly from Source Control, as we saw earlier in MATLAB, that's one of the options. Then this would already populated for you with the type of Source Control integration you have like Git and where is the remote repository location. But if we just want to set this up for local Source Control, we can just add this project to Source Control.
And it's going to run a few simple checks very quickly. They should all pass. And then you'll see a new column inside of our project window, something called Git. So Git, I've mentioned this a few times. It's one particular type of Source Control software. It's a very popular one. It's the one that's used by default in MATLAB.
And if we look down at the different files, you can see that there's some symbols going on. If you mouse over that, it'll give you status updates for what's its relationship in the Source Control system. So right now the little plus is telling us, OK, we've added it to Source Control. Source Control is now aware that we want to track this, but we haven't actually committed it yet and told it to take that snapshot.
If we want to do that, we can come up to the big Commit button, give it a little message like, this is the initial commit of MATLAB files. And that's it. And now we've told it to take a snapshot of the current state. It's added all of those files to the Source Control repository. So we can see-- now we get a little green marker telling us it's unmodified.
So we don't have any changes in our local file that aren't reflected in the Source Control system. And that's really all it takes to get started using Source Control in MATLAB. And we'll come back and use this a few more times today as we make additional changes.
But with that, we're going to tab back to Slides. And we're going to keep moving along to our next topic and arguably the most important one, which is automated testing. Now, our advice is to test your software early, test it often, and test it automatically. This has a bunch of benefits to it.
One of the biggest ones is you are formally documenting the expected behavior because you've written down in your software tests what you expect your software to do. This lets you catch problems early and reduce the risk that your code is going to break later. Another question I often get, especially at this point, is do I really need to do software testing? I mean, my code looks like it works, and this feels like a lot of work.
And my response to this is always another question. Do you care if it actually works? Do you care? If you do, you need testing. Because software testing is the only way to make sure that your code actually works the way you think it does. If you don't care if it works, well, that's sad. I'm not sure why you're spending your life working on stuff if you don't care if it works. But OK, if that's really the answer, then maybe you don't need testing.
Now, there are a lot of different types of software tests out there. One of the most common is something called a smoke test. The name smoke test comes from the field of electronics, where a very fast and easy way to test for a major problem is to just turn on a device and see if it starts smoking.
Smoke tests in software kind of do the same thing. They are meant to be very fast and easy ways of testing for major problems with whatever it is that you're building. If you have a script, just run the script. If you have an app, launch the app. If you have a function, call it with basic inputs. If that doesn't error, then that's a successful smoke test. That's really all a smoke test is.
Another common type of test is a regression test. A regression test tests your software to see if it still has the same behavior as it did before, after you've made a code change. So the idea is we're starting with one version of our software. It's producing a certain output. We need to make some kind of a change to it. Maybe we're improving it. Maybe we're refactoring it. Maybe we're fixing what we thought was a bug.
And we need to make sure that after we're done with the change, we didn't unintentionally change the behavior. The regression test is going to look at the output and see if it's the same as it was before. It's important to note that sameness-- rather, it's looking for sameness, not necessarily correctness. It's up for you-- the person writing the test-- to make sure that sameness is, in fact, correct.
And there are many other types of software tests beyond this. We could easily spend the whole hour today talking about them. There are things like performance tests measuring how quickly and efficiently is your code running, security tests, testing if your system can be compromised from the outside, and many more beyond that.
Today, we're going to focus on a simple regression test. Now, as a part of building our prototype, at some point, we needed to create a custom matrix multiplication-- so a good old row times column, linear algebra, matrix multiplication. But while following a special rule, any time there is a NaN multiplied by a 0, we wanted it to output a 0 instead of the default value of a NaN. We don't have time to get into why today, but you'll just have to trust me.
At some point in building the prototype, we had to write this kind of a custom function. So as an example, if I had these two matrices here and we did a matrix multiply, the default answer is going to be the one on the right. But that's the one we don't want. We want the one on the left. And notice the difference is in the bottom right corner, the 2 comma 2 location, which results when this NaN gets multiplied by 0.
Now, the first thing to realize about software testing is you already write tests, even if you don't think about it that way. If someone gave you this function and you weren't sure what it did or you weren't sure it worked correctly, what's the first thing that you would do? Most of us would probably just go to the command line, create a few simple inputs, and then run the function and see if it looks right.
This is called manual testing. And it works, but there's some problems with it. First off, it requires someone to remember they need to test the code, then know enough to conduct the manual tests, and then understand the problem well enough to judge for themselves if the output is correct. There's a better way to do this, which is formalizing it with something called a unit test.
With a unit test, we write down the expected behavior in a file that we can run repeatedly. And oftentimes this file can look pretty similar to a manual test you might do at the command line. So inside of this unit test, we're going to write down the two inputs. Then we're going to write down our expected answer. Then we're going to run the function with those inputs and compute what the actual answer is.
Then we can use a particular function. And MATLAB has a large family of these functions that vary in different ways for helping you determine if your software test is behaving as you expect. The most commonly used one is verifyEqual which, as the name suggests, will verify if the actual and expected answers are indeed equal.
If they are equal, the test passes. If they aren't, the test fails. And whenever we're ready to actually run our tests, we can do that either interactively or programmatically. So with that, let's hop back over to MATLAB and get started writing some unit tests.
So the function we're going to work with here is something we called Station Multiply. This is our custom matrix multiply function. We're not going to worry about its implementation today. But as we talked about in Slides, you might start by, let's say, trying something at the command line, creating a small set of inputs, and then just running it interactively and seeing if it returns the result you expect.
A better way is to formalize this with a written unit test. Now, you've been able to do this in MATLAB for many, many years. One way is to come up to the New tab and get a new test class. This will generate a template for you where you just have to fill in the blank, fill in the function with whatever your test is.
But starting in the 24a release of MATLAB, there's an even easier way. If you want to create a test for a file in MATLAB like our function here, you can right-click in the Editor and just go to Create Test. This uses something called MATLAB Test. MATLAB Test is an add-on product to base MATLAB that provides advanced functionality for testing, including automated test generation.
So this will automatically generate a unit test file for us. It'll add in some comments, kind of explaining what the different parts are. So here, it's telling us we need to specify the inputs of station multiply. And it's giving us some incomplete statements for us to kind of fill in the blanks. So I'm going to copy-paste what I had from the command line up here as our first input and then our second input and then the output that we expect.
Then the generated code is going to automatically run the actual function to produce the actual result and then use verifyEqual to verify that the actual and expected answers are indeed equal. Before we run this, we need to save it. And I'm going to follow the MATLAB Toolbox model. I'm going to create a new folder for my tests and I'm going to save my file in there with just the suggested name Test Station Multiply.
And then, both our project and Source Control by default don't assume we want to track anything. So I'm going to go ahead, and I'm going to add that to my project so that everybody who uses this project gets it. And notice with the Source Control status, that action is automatically going to add it to Source Control as well, because Projects integrate very tightly with Source Control.
So now that we have our unit test written out, and we've got it saved and added to our project, we can go ahead and run it either from the tool strip or programmatically. And this will open up something called the Test Browser. The Test Browser is great when you have lots and lots of tests. We just have the one today, so it doesn't look like it's doing much.
But as you can imagine, on a large project you might have dozens or even hundreds of tests written out across many different files. And the Test Browser gives you a very quick and easy way to search through all the different tests you have to see which ones are passing, which ones are failing, and why might they be failing.
But for today, we just have our one simple test. Everything's working as we expected. And now that we have this one test, we can easily add more tests by just inserting another test method. So this will add another function to the list. And now all we have to do is fill in the blank.
So inside of this test, we'll do something kind of similar that we did before. And we need to write that test such that if our software is behaving the way we expect, everything runs fine without any errors. And if our software is not working the way that we expect, then it's going to error, possibly using something like a verifyEqual.
But for our purposes today, we're going to leave it with just that one test. And we're going to follow best practices, and we're going to make frequent small commits. So we're going to go ahead and commit this and say this is the, let's say, initial commit of testing file. And there we go.
And so inside of MATLAB, you can write unit tests either from scratch yourself or using MATLAB Test-- automatically generate unit tests for you where you just have to fill in some of the blanks, much like you would inside of a manual test. And with that, let's go ahead and hop back to Slides and jump into our last topic for today.
So at this point, we've laid out MATLAB Projects and Source Control and testing. So we're starting to build up kind of multiple steps in something like a workflow. And so the last thing we're going to talk about today is capturing and automating those workflows using something called a build file.
So a build file is just a function file in MATLAB, and you can see an example here. And that function file defines the different major tasks that you can perform with this project and how they relate to each other in a workflow. Like the Git API we talked about earlier, this is one of the newer things in MATLAB. This first came out in 22b, and we've been improving it every release since then.
You can create a default build file. MATLAB can create that for you using Build Tool-Init. And then you can import or write the tasks that you want to automate with your build file. So at the top of this example build file, it's importing all of the built-in tasks for us to play around with. Then at the bottom, you can see we're defining a custom task in a local function.
This particular one will build a custom Toolbox programmatically. And these types of custom tasks, you can automate anything that you want. Anything you can script in the MATLAB language as a function, you can automate as a task with your build file.
Once you create or import the different tasks that you want to perform, you can then create what's called a build plan. So the build plan, this is just an object in MATLAB. It will live in the MATLAB workspace if you were to pause the debugger in the middle of this function. And there's a number of different ways to create it. Here, we create it from our local functions.
So it starts by looking at our Toolbox task. And then we can add on any of the built-in tasks that we imported earlier. So one we'll import is the code issues task. And this will programmatically check for warnings and error messages from the MATLAB Code Analyzer. Those are those orange and red squiggly lines you might see under your code from time to time.
And the code issues task will look for those. And if there are any errors, it will automatically abort the workflow early and let us know. The test task is another built-in task that will automatically run any software tests that you've defined and abort the workflow early if those tests are failing.
We can set any dependencies between them to define a workflow, as well as defaults. So with the check task, if the MATLAB Code Analyzer already knows that our code contains errors and isn't going to work, we probably want to know that and deal with that before we even bother running our tests. So here, we're going to make the test task depend on the check task successfully completing first.
Then if we want to package our Toolbox, well, we probably don't want to do that if our tests are failing. So we're going to make the Toolbox task depend on the test task. And then we can define defaults. And let's say by default, we just want to package our Toolbox.
Once we've set up our build file, we can then use it from the command line, using a command called Build Tool. Build Tool can list out the relevant tasks that we have, as well as run any of the ones that we've defined. In this case, using Build Tool we're just running the default. That will try to run Toolbox.
But Toolbox depends on test, and test depends on check. So first it runs check. And if that successfully completes, then it runs test. And if that successfully completes, then it will run Toolbox.
So the build file and Build Tool, these are fantastic general purpose tools for documenting and automating workflows in MATLAB. I've become a big fan of it. I use it all over the place because I'm really bad about forgetting some of those intermediate steps. Like, hey, I should probably test my code before I package my Toolbox.
The Build Tool also serves as the gateway to what are called Continuous Integration or CI systems. Continuous integration systems are fantastic tools for automating, building, and testing your code. The general workflow is you have a collection of developers working in MATLAB and maybe other tools. And they are collaborating through and making commits to a source control system to track all of those changes.
Whenever the continuous integration platform sees a change made in the Source Control system, it can automatically grab the latest version of all of that different code from all the different people working on it, build all that together, run all the tests, and then automatically report all of those test results back to the developers. So they're getting feedback in near real time. And depending on the success of those tests, it can then potentially even take further steps like deploying software to endusers.
MathWorks provides plug-ins, as well as the MATLAB Build Tool, to streamline connecting MATLAB and setting up MATLAB CI jobs in all of the major continuous integration vendors. So there's a bunch of different ones out there. We have great support for all eight of the ones that you see here.
And if you have a public GitHub repo that does not use R compiler or Coder products, you can use GitHub Actions, which is the GitHub CI tool without any kind of a license or cost. You can use it completely for free. And this is a fantastic option for doing things like open science and reproducible research in academia, as well as community toolbox building.
Now, the details of setting up and running inside of a CI system, that's more than we have time to get into today. For now, we're going to hop back to MATLAB for the last time. And we're going to see how we can add a Build Tool to-- or build file-- to our project and leverage it with Build Tool.
Now, if you ever come across a topic in MATLAB and you're new to it, and you aren't sure where to start and want to learn more, the first place I always encourage people to go to is the documentation. So let's say after today you wanted to learn more about the Build Tool. I would go straight to the Build Tools documentation page.
We at MathWorks are very proud of our documentation. We think we have the best documentation in the software industry. And I strongly encourage all of you to make good use of it. Every command in MATLAB has a documentation page with the same format, beginning with syntax, different ways to use it, detailed descriptions, and then my favorite section, the examples.
So the examples for the Build Tool will show you things like here's what an example build file looks like with comments explaining what everything inside of it does, and then different examples for how to run things with Build Tools. So here's how you run it with the default. And here's how you specify a particular task that you want to do. These examples then also always run into more advanced use cases.
So, for example, how can you create a custom task that accepts arguments to customize its actions? And it'll show you a great example of defining your own custom task where you can customize how it's going to run, and then how do you actually call that and specify those optional arguments. So strongly encourage all of you to make good use of the documentation.
For today, we're just going to start by generating a default build file by saying Build Tool dash Init. So this created a default build file for us. And you'll see that if you do a few things for us, it'll import all of the different built-in tasks. It'll then create a build plan. It'll start by looking for local functions. We haven't defined any local functions here. There aren't really any that are relevant for our particular example.
But as you saw in the documentation, if we wanted to, we could add another function down here and define any type of custom behavior-- anything you can script in the MATLAB language-- in our local function down here and create our own custom tasks. It'll then, by default, add three tasks to the build plan.
Two of them we talked about before, the code issues task and the test task. The clean task will just delete any artifacts from prior runs of the Build Tool. Sometimes when you run the Build Tool, it will create some files to keep track of anything and report on results. The clean task just tells it, hey, go ahead and delete all of that so we're starting fresh.
And then as we saw on the slides and talked about earlier, If we wanted to create a workflow and add dependencies, we can do that very easily. Let's say I want to make sure I run the clean task before I check my code for warnings and errors. And I want to check for warnings and errors before-- whoops, I had a typo there in plan. I want to check for warnings and errors before I run my tests so we can very easily build a workflow.
And then by default, let's say I want to just run my tests. Before we use this, we want to save it and then add it to, again, our project and our Source Control. So we can add it there. And now that we've defined our build file, we can use Build Tool to ask and double-check, hey, what are the tasks defined inside of this build file? There's three-- there's check, there's clean, and there's test,
And if I just run the default, you can see it's going to honor that workflow that I defined. So it's going to start with the clean task. When that completes, it's going to run the check task. When that sees that there's no errors in any of my code, it's going to run the test task. And it'll tell us how many of those tests passed or failed.
OK, and that's actually going to conclude in MATLAB portion of today's demonstration. We looked at a number of different topics like Projects and Source Control and unit tests in the Build Tool. Let's hop back to Slides to summarize and wrap up what we talked about and talk about where you can go next.
So we introduced three key topics today for building better software. When it comes to organizing your software, we talked about the MATLAB Toolbox organizational model and getting started with MATLAB Projects. We introduced the basics of getting started with Source Control, using local repositories and making commits. And we talked about automated software testing by creating unit tests to verify the behavior of our software and automating software workflows with the Build Tool.
Each of these topics has much more to it. When it comes to architecting your algorithms and your code, that's a topic we kind of just skipped today because we simply didn't have enough time. But there's a lot of very interesting and powerful tools in this area-- a lot of them related to object-oriented programming, things like encapsulation, polymorphism, namespaces. These are all great terms to go look up if you want to learn more.
When it comes to Source Control, as we mentioned earlier, remote repositories are very powerful for backing up your work and sharing and collaborating with others, as are things like branches and submodules. When it comes to software testing, there are many other types of tests we didn't talk about today, as well as test metrics for measuring how your tests are performing, tools for managing your tests, as well as generating tests automatically for you.
And much of this can be enhanced or done using the MATLAB Test product. Almost everything we talked about today is just core MATLAB. But the MATLAB Test product is a relatively new product that enhances MATLAB software testing abilities. Then when it comes to automation, we introduced the concept of testing automatically with continuous integration.
As we mentioned back at the beginning, our consultants have learned after many, many projects, these are some really critical areas that it's important for everyone to get right. But there's also many other things to think about and try to incorporate-- all those other topics from way back at the beginning of the presentation-- things like coding standards and upgrade strategies and performance benchmarking and many others.
So if you want to learn more, where can you go from here? Well, there's always the MATLAB documentation. We looked at that. We have a lot of other information on our website. And you can always reach out to us, and we're happy to talk more one on one.
But if you're feeling really lost and you want a customized, bespoke roadmap specific to your project, this is a place where our consulting organization can help out. They have something called a Technical Computing Process Assessment, which is a very lightweight, very fast consulting project that will have our consultants come on-site, interview you and your colleagues to learn about your project's goals and your particular skill sets.
Then they will evaluate your code base and provide a report that provides measures along seven pillars of software maturity. You can see those onscreen. And some of them, like architecture and testing, should be kind of familiar after today. That report will define where you are today, where you need to get to in order to be successful with your project, and provide a recommended path for how to get from point A to point B. Part of that path might be some training and upskilling for you or your colleagues.
And we provide a wide variety of training classes all along the spectrum, starting from the core basics of MATLAB fundamentals to classes built more for individual engineers and scientists who just want to get better at writing scripts and functions for themselves, all the way up to people who are writing large apps and even entire MATLAB toolboxes that are being used by hundreds of people across their organizations. So whatever your end goal is, we have training classes to help you get there.
And then last but certainly not least, I encourage all of you to make very good use of MATLAB Central. MATLAB Central is our community site where over 2 million monthly users come by to get questions answered on the MATLAB Answers Q&A forum or download or share code through the file exchange or read blogs that are written by the engineers who build MATLAB and Simulink. And with that, that's everything I had for you today. Thank you all for tuning in.