 All right. Thank you very much. Hey, everyone. I'm so glad to be here. Shout out to everyone all over the world who's watching this. I was able to make it. My name is Tony, Tony Shodara and I'm a software engineer based out of Lagos, Nigeria. I'm also a Microsoft MVP for developer technologies, and I enjoy working on and contributing to open source software. Today, I'm going to be showcasing one of my projects that was both challenging and pleasant to build. It's also received a considerable amount of our community optic. It's called Covalent, and it's not the first we see, but I'll say it's still the most used cross-platform code coverage tool for .NET Core. Before I go, this is going to be a demo-heavy presentation, but before I jump over to like showing us code and terminals and stuff, I'm just going to give out a bit to explain Covalent and how it works. Over to the next slide. Typically, the standard way code coverage tools work in the .NET framework was that they made use of the profiling APIs. However, in the early days of .NET Core, and I think at this point, it's still the profiling APIs are not yet fully fleshed out as they are with the full framework. As a result, the popular tools like OpenCover, the cover that we're used to using on Windows with full framework have not been ported over to work with .NET Core. So I decided to fix to come up with a solution that bypass the profiling API altogether. So how Covalent works is basically, it recognizes your unit test assembly, picks out the dependencies from your test assembly, then Covalent injects instrumentation code within those dependencies because naturally, if you have a test assembly for the main project, then it needs to pick up the main project. So it takes that main project, it inserts inject instrumentation code, and then it goes ahead to run the tests. So while the tests are running, the injector code within the assemblies are constantly recording the code parts that are hit to a temporary file, and then once tests are complete, Covalent takes up from there, calculates the coverage, and once it's done with that, it restores all dependencies back to the original form. So you do not have to do any manual cleanup yourself. All these processes are of course fully transparent to the user. They do not need to interact with them, and from the user point of view, all you have to do is run a command and view your results. So I'm going to jump right over to a demo now, so you can see Covalent in action. So over here, we have a typical.NET Core solution. We have the SLM file, we have the source program, which is where our code lives, and then we of course have the unit test project. So I decided to show something really easy and simple that we can all understand real quick. So I created a simple math class that comes with four different methods. So we have the add method, we have the subtract method, we have the multiplication, and we have the division. So it's simple, pretty straightforward, add, add, subtract, subtract, multiply, and it goes on like that. Then we have the test project, which basically tests out the individual methods that we have over here. So you can see here we have a method test for the add method, we have a test for the subtract method, we have a test for the multiplication method as well. There is no test for the division method, and I'll show you why in a bit. So the very next step here is, I'm just going to go around the test for now, just so we can go into the test folder, and then you can just run the .NET test as you usually view. I mean, standard practice, all this does is build a project and run the test. So all our tests are passing great. However, there's something I'd like to do, I would like to see how much of my code has been covered by my unit tests. So notice that I'm working with a MacBook, this will also work on the Windows and Linux, and I probably will test that out later if we've got time. So the first step will be to add coverlet to your project. So coverlet is available in two flavors. You can either have included as a package in your unit test project, or you can install it as a global tool. So including it as a package in your test project allows coverlet to integrate fully with your build pipeline. So I'm going to show you both approaches to using coverlet. So we're going to start out with the most straightforward one, which is using it as a package. So to do that, all we just do is add package, coverlet, MSBuild. By the way, this is also coming from a public library repository. And yeah, there we go. So using coverlet is straightforward. So we have a net test that we used before. Now we want coverage information. So to do that, we just add a new property, collect coverage, it goes to true, and we let it run. So over time, I should mention that the performance of coverlet has really improved. So now it adds very little overhead to the test run. There was a time we used to add times two. We used to take double the time to run your test when you're being in coverlet. So we can see here, by just adding this extra property, we see that coverlet automatically integrated itself without us having to do any extra setup. So you can see in the test run, everything passes. Yeah, you can see it's generating the JSON result. And then you can see a summary. So if you come over back to the code, you can see. Yeah, so this is a very simple JSON file. So this is coverlet's own code coverage format. It's basically a straightforward JSON that contains the line information, the branch information, as well as the method information. This is the result. And you can see this is a very straightforward summary result. So I mean, from the result, you see we're not doing so well. Our method coverage is at 75%, which is hugely unacceptable. If you come over here, it's because, of course, we have four methods, and we didn't create a test for the div method to naturally 75%. You can see our branch coverage is exactly 50%. And we attribute that to the subtraction method, because you can see it has two points of two possible execution path, when the second argument is zero, because we do not want to want to divide by zero exceptions. And of course, when that's not the case. So we see that if we look over at our test, we see that we are only testing the path where the second argument is not equals to zero. And of course, we have the line information which tells us how much, in terms of how much of our lines have been covered. So before I jump into improving the coverage result, I want to show you all the other different formats that cover that support and how to work with them. So this is, of course, the program that we ran previously to get the coverage results. So to get a new format. So apart from the JSON format, Covalent supports three other formats, which is OpenCover, Covertura, and Elcorp. So you can use the Covalent output format property. So let's call OpenCover. So build that, launch your tests, generate your results. Get them over here, and you can see the OpenCover information over here. So I'm going to do that for Covertura as well. I hope this is how to spend it. Remember, OK, runs great. And then we can see Covertura. So guys who are coming from the Java world and everything would be a lot familiar with our Covertura. And we have Elcorp. Elcorp is pretty popular, especially in the Linux world, where you can use GenATML to generate an ATML report. So you can see we have our coverage.info, which is Elcorp file. It's also a pretty popular format. We have our Covertura format. We have Covalent on JSON format. And we have OpenCover format. So this is done so that you do not have to start creating converters to convert between formats just so you can work with your existing tools. I decided while building this, I decided to pick some of the most popular formats so that you can just use it out of the box and could be a drop-in replacement for whatever tool you were using before. OK, so now we're going to go over to understanding how to enforce certain coverage requirements with Coverture. So as you can see here, we have a line coverage of 71.4%, branch coverage of 50%, and a method coverage of 75%. So imagine if in an organizational setting where we have a best practice, I'll call it a threshold for what our coverage percentage should look like. So with Coverture, you can set a coverage threshold. So I'm going to go ahead and set, let's call it 100% because we're perfectionists. So yeah, so it's going to be that it's going to run our coverage and then it's going to grow errors. So you see, we still get our coverage summary, but then we also get an error that says, OK, our line coverage is below the specified threshold, branch coverage, and our method coverage. You can, of course, specify that, OK, you only want to enforce the threshold for, say, the method coverage, for example. And if you do that, you'd see Covertlet, we only throw a single error. Well, yeah, we wanted a crossboard, so let's leave it at 100%. So let's go back to the code and sort of see how we can get over to 100%. So the first step for that will be, of course, we can look over here and say that we're not testing the div method. So we can just go ahead and add a test for the div method. Set the equal, just take the 100, math.div, 101. And so let's go run it again and see how that changes going to improve our coverage. All right, so we can see our line coverage has gotten a bit better. And then, yeah, we got our method coverage at 100%. Take a look. Now we only have two errors, which is the line and the branch coverage results. So let's go over here and improve the branch coverage. So we need to test this path of our subtract method. So I'm just going to have other simple stuff here, and show you return 0. Probably should have been for divide. But anyway, that's OK. And then we test that here. And then you can see we don't have any errors. We're covering all our branches. We're covering all our methods. And we're covering all our lines. And yeah, that is straightforward, pretty straightforward. You don't have to do so much setting up or preparations to get started and productive with Covalent almost immediately. All right, so I'm going to move over to showing us the other way of using Covalent. Because this was the approach originally used when I developed it. But then you had people who did not want to, of course, pollute their dependency trees with extra packages that they only needed in development. They didn't want to have to add a new package that's going to make it a production that's only for development purposes. So I'm going to remove the package now. And then we're going to see how we can install Covalent as a tool. So we should. OK, so it's out. Let's get rid of all this stuff here. Great. All right, so now we no longer have Covalent included in our package list. But we still want to get coverage results. So what we can do is we use the new Google tools feature in .NET Core. I think it came out with .NET Core 2.0 or 2.1. I can't really remember. But then all we do is .NET to install global Covalent.Console. Of course, this is also a nugget. Then we do that takes a while. And then if you just type Covalent help, you can see the help on stuff for Covalent. All right, so Covalent works the Covalent Google tool works slightly differently from the MS build or the build pipeline integration approach. It requires a bit more prep to be able to get it done quickly. So the first step is we need to specify the path to the test assembly. So by path to the test assembly, we mean the path to basically the compile DLL, which would be this guy over here. So I think I'm just going to go ahead and use. So I'm just going to notice that I'm in the test folder. So I'm going to just do 2.1, confirm, .NET tests. So now we have to specify the target. Now, because we do not integrate with the build pipeline, we have to ensure that we specify our test runner. So in this case, our test runner is going to be .NET. We're still using this typical .NET test infrastructure. And then have target ads. So here, .NET tests are all good. We are in the directory for the test. So we do not need to specify the path to the CS project. We can just put. So this is basically the equivalent of running the .NET test within this directory. Also, something very important here, we have to specify the no build flag. And the reason is, remember when we were talking about the covalent internals, right? Covalent injects code into your assemblies. So if a build happens, because usually when you run .NET tests, it does a build first and then runs your tests. So specifying no build says, OK, just run the test straight up. Do not build because covalent actually instruments, you are sending this before it runs this. So you need to ensure that running this does not remove the instrumentation code that covalent injects. And I should also mention that you shouldn't be too concerned about covalent injecting code, because at the end of every run, it's make sure to put back the original. So it was like it was never touched. And then, yes, so we have, so this should be all. So you can just hit Enter and watch it through its magic. And there we go. So we have all our tests passed. We see we are seeing the exact same information from above. We're using the global tool. That's because, of course, the package as well as the global tool share the same core functionality. So all that's different is how you use it. So yeah, this is covalent stuff. We can, of course, specify. So you can see the information on what exactly you can specify over here. So we can, the threshold, the threshold type that we did, you can exclude and include as well, which is also possible with the package, the MSBuild version. Can exclude certain source files so it doesn't, especially when you have situations where you auto-generated some files that basically should not be included in a test run. And of course, you can merge other with other results of other runs, basically. I'm just going to jump over to the sky to see if anyone has any questions. If not, just move on to sharing a bit more with covalent. So not that you've seen the global tool and you've seen the MSBuild. I'm going to try to integrate this with a CI server, basically, so you can see how then you see covalent run on, I mean, a Windows machine, you see run on Linux, and then if you have time, you can maybe push it to some coverage hosting service. So I have, yes, you can all go over here to get a demo of this code that I have. So I'm going to just integrate this with AppDevail. That's typically my CI of choice, usually because it's got Windows and Linux build machines. So I'm going to just sign in over here. See, all right, so I'm going to add new projects. OK, sorry about that. I'm going to be hard, I wish it to do before. So over here, so we add that over here. Awesome. And then let's come back to our code. So I'm just going to copy off some previous stuff that I did. So we had the typical AppDevail, the YML, awesome. So I'm just going to breeze through this. What are you doing? So I'm going to specify that AppDevail should use Visual Studio 2015, which is going to be the Windows build agent, as well as Ubuntu, which is the Linux build agent. I'm going to have configuration about this. Ooh, that was close. And then for our build script, let's do a simple PS. I love using PowerShell, by the way. Give it a vision. Yeah, just put that in. And then simply do a .NET build in the root of the folder. All right. And then for the test script, I'm going to just have it run .NET tests P, collect coverage. Equals to true. Probably shouldn't forget to add that back over here, because I find that using the package approach tends to be a bit more convenient, because then you don't have to start running .NET Core global tools on your CI server. But whichever one works for you, basically. You work it the way that I must build. Just add that. Great. So I'm going to go ahead and just make sure I don't have any typos. Yeah. So just go ahead and put meets, add and improve coverage, commit that, and then we add that up very well. All right. So we just push that over to the repo. So awesome. OK, so we got our first error. I have a typo. So let's look for that. I see there you are, which is great, by the way, because I use CircleCI sometimes. I knew we have an error in the configuration of our. It just doesn't build. So this is the first time this is happening to me. And it's pretty nice. So fix typo. Let's see how that works. OK, let's take a look. See if I've fixed it. OK, so as you can see, we have tests running on, well, two different build agents in two different releases each. So we have the debug configuration for Windows. We have the release configuration for Windows. We have Ubuntu, debug, and Ubuntu release. So we can just leave this to run and let's leave it to run. So I'm just going to move over to the Covalent repo itself, which it's pretty active. So I constantly commit. I typically have people open up issues and happy hours from the community. So here you'll find huge detail, all the documentation regarding Covalent from, of course, talking about how it runs. So you can sort of understand that. And then we talk about usage with both the global tool format, as well as using the MSBuild format. Let's see. There's the MSBuild format. Yeah, so you can see how to do things like specify multiple output formats in a single run, how to merge results, how to, I mean, you already saw how to do thresholds and stuff. And then, oh, yeah, something I should try to do. Let's go. I want to show you how to exclude certain things from being included in coverage calculations. So let's go over here and let's just temporarily comment this out. Come back here and do a dot let's test, collect coverage. And then wait. So you can see, oh no, our method is at 75%. Line is at 78.6%. So what we want to do, let's assume, well, the div function is still under, the div method is still under, what's the word? Developmentally, we're not ready to include it in our coverage yet. There's still a bunch of proof of concept going on in there. We can just use system, I think it's a diagnostics, the code analysis, yes. And then you can just apply this attribute onto the div, of course, coming from this namespace. And you can see that when you go to run the coverage again, you see that the div method basically had no effect on our final output because we told coverlet to completely ignore it. So that's pretty convenient for situations where you do not want certain unfinished methods to pollute the coverage results. And if I do you one better, I'll show you the coverage of JSON that was generated. And you see that doing a search for div is low results. Well, if you search for sub, which are the other methods, you want to do the odd method, you find all those over there. That's pretty cool. Hopefully, you find it pretty cool. All right, ooh, that's the feeling. Let's find out why. Excuse me. It's red. Oh. OK. So I need to just fix something real quick. On that build, I want to have dot net tests, tests, slash. Let me just do. That was not supposed to happen. Let's see as project. So this should fix it. And I think that should get it fixed. I'm going to test and just go from that. And let's try again. Let's do another push. OK, so all right, so we have another one running in a bit. All right, so while this is running, I'll just talk about visualizing your coverage results. Because look at it this way, right? You have all this information stored here. You have all the stuff in here. But it's not particularly humor-readable. You can, of course, write a piece of code to pass this information and give out a bit more context. But well, it's a lot easier if you have some sort of graph or charts and stuff to take a look at stuff. So I'm just going to discard all this. So I want to talk very briefly about what's called Report Generator. So those of you who use the open cover and windows a lot, you'll be very familiar with this particular project from Daniel. So what it does is it takes in XML reports in this format in any of these, and then generates into basically something like this. So while this is happening, I'm just going to go over here and try to work with it. So luckily, it has a global tool option. I haven't used this global tool before, by the way, but I'm just going to copy that out. Just going to install that. Awesome. So I think it uses the reports generator command, ip. Great. So the first thing I'm going to do is generate. The first thing I'm going to do is to generate a co-coverage result in the open cover format. So we're just going to use the previous. So I'm going to let our format tell it to use open cover. We're going to, of course, use cobertura, since the progenerator supports cobertura. Great. Awesome. So this is a very straightforward example. So I'm going to run progenerator, progenerator. I'm going to have, so I'm just going to copy this. Of course, I'm going to edit it a bit. So I want it to be in the report folder. It's also dot, let me confirm that. It's also cobertura.opencover.xml, opencover.xml. So let's see how that works. Ooh, great. So over here, so we have the HTML file. So I'm just going to open this up. Let's see. Let me review and find a case. I'm just going to click that. Ooh, all right. So yep, so we can see our information. We can see it very, it shows us, we can go here. We can see all that information. We can see each line that is covered, which is absolutely great. We can see the line coverage. We can see the branch coverage as well. I don't think it does method coverage. Yeah, so this is pretty cool. So straightforward, very close platform way. You can get information about how well your tests cover your code. So that's pretty good too from Daniel. Thank you, Daniel. Oh yeah, so we can see on Windows, we can see that one of our stuff over here passes, built success, and we see the coverage results generated. So I'm just going to wait for this. We're almost done. Oh yeah, by the way, Covenant also uses, it's sort of like a dog food in process. Covenant uses its own, basically, Covenant runs tests on itself. And we use that to generate this handy little badge over here that we integrate with code code, which is pretty popular. You have other ones that cover all that stuff. Also, let's see. So over here, you'd see that Covenant is working, is using the XUnits. We're using the XUnits test framework. Just a good note that Covenant works, basically, with any test framework that integrates with the .NET test functionality in the CLI. So whether it's a popular one or it's one within your organization, Covenant will be able to work with it as long as you have it integrated with .NET test. Also, using the global tool, even if it's not integrated with .NET test, because you, of course, have the ability to specify things like the test runner and the arguments to those test runners, ideally, Covenant should be able to work with basically any .NET unit test runner out there. So we can see the Linux build over here. And of course, we can see our coverage information. Yeah, so I'm going to go back to the slides now, as that's pretty much it for the demos. All right, the slides. Great, I'm going to play from here. All right, so as I mentioned earlier, we have a bunch of hosted coverage services that Covenant works with. So it works with CodeCode using the open cover format. It works with CodeClimate, also using the open, using the Covenant format. And the L-Cov as well, because L-Cov and Coventura are supported by CodeClimate and Covenant. Then there's also VSTS, that's Visual Studio Team Services, although now it's called Azure DevOps, which is pretty cool, especially because it gives you three different build agents, Windows and Mac, as well as Linux. And then you have SonarQ, which is another hosted service that you can also use SonarQ with Coventura or the open cover format. And then you have Coveralls, which would also work with the open cover format that Covenant generates. Yeah, so let's move over. So this part, I'm actually quite excited about this part. We have some projects over time that have been using Covenant to get stuff done. So GitHub uses Covenant for their OctoKits.NET clients. They also use Covenant in their GraphQL.NET client as well. Microsoft and the Runtime Devs, the .NET Runtime Devs use Covenant to get code coverage for, they use Covenant to get code coverage for the Linux builds for the, basically for .NET core effects. So for those who might not be familiar with that term, .NET core effects is basically more like the base class libraries for .NET framework, but actually inside for .NET core and they are a bit more modular because they are distributed as nugget packages as opposed to being included in the runtime. And then you have Sentry, which is a fairly popular application performance monitoring service that uses Covenant with their .NET client. Well, also actually, I think we've only fair to mention some other alternatives because even though Covenant is by far the most popular cross-platform solution, it wasn't the first on the scene. And sometimes you might have certain specific requirements that Covenant might not be able to meet or I might not be willing to add, depending on how much interest it has. So usually you could just use the other two, which is a mini cover by Lucas Lawrence and then out cover by still Bill Ham. So these two Dev projects, they try to achieve the same result as Covenant, but of course they do it in a completely different way. So for example, with mini cover, you have a bit more control over the entire process from things like what are these instrumented, think what directories you want to find all your source files from. And even up to you having to do the instrumentation yourself to ensure that you have release ready packages. Alt cover is also a very well-featured project as well. So you can check both of them out and see just in case Covenant doesn't meet certain needs. Then, yeah, you can get in touch with me on any of these mediums. I'm basically tornado about everywhere. So I tend to write a bit on medium. I haven't written in a while that I've been focused on to work on Covenant, but you can catch me on there, I'm on Twitter and on GitHub, and then here's my email if you just have any information to share with me. And yeah, thank you guys for checking in. Do we have any questions? Actually, we'll have to check questions live. No, yeah, so we've been monitoring the chat, Tony. I don't think we have any questions, a lot of good comments. A lot of people say great demo, they really enjoyed it so far. I really enjoyed it over here, kind of learned about it. Now, you did say that, I have a question, I guess. You did mention that it works with any of the .NET test runners. So N unit, MS test, and X unit, all of them. Yeah, all of them are supported. That's awesome. I just want to make sure I figure to give the whole list out, but yeah, I think that's cool. Yeah, and if you've got anyone that isn't so popular, as long as you have a runner for it, you can basically use it. You would already matter. Awesome, yeah. I think that's all the questions over here, Tony. Thank you so much for showing us all the goodies. Yeah, I'm looking forward to be able to link to your talk. Every time I get a question now about how to test the .NET libraries, I will point to your talk. Cool. All right, Tony Holtz. Thank you very much. All right, cool. Cheers, we'll have a lovely, lovely day, and thanks for the presentation. All right, thank you for having me. I really enjoyed myself. Well, have fun at the rest of the festival. See ya. See ya, bye. All right, we have the, go ahead and you can log out. Let's see, we have the one and only Jeff Fritz over here who tells us that audio is working. Audio is working. Audio is working. Hey, hello at lobe.netcom. Yeah, we'll see. We'll see. Well, Emo's not even in there anymore. There he is. We'll see. He says that the audio is working and I say great. And the party just arrived. Which is great. So everything's live, we're here. You know, we all purchased iPhones, I believe. Not for me. I didn't buy one for myself because I'm an Android user. Did you buy one? I did not buy one yet. I know. I was coder. I see some folks. I've seen the.net bot salutes at low and low. Good morning, good afternoon, good evening. I'm wearing, this was the only hat I had with a bird on it. How do I get a C-sharp bot? You get a C-sharp bot if you are a subscriber to my channel. Oh, I see how it is. But you can use your 20 Prime subscription over there for free. But here's the thing, every one of those is a donation to girl development. Oh, that's pretty great. That has a nice hat. So, yeah, absolutely. What's your, what's your Twitter channel for people don't know? C-sharp Fritz. C-sharp Fritz. Just like the Twitter. C-sharp Fritz. Boom, I'm at James Johnson Magnum. That's my name. And I am a Amazon Prime member. They still give away a free one. Amazon Prime, you get a free Twitch Prime subscription. You get one channel you can subscribe to for free. Every month. Every month. And absolutely, it is for good cause. You know how this works. Now, I should probably do it while you're actually streaming because you probably have like Streamlabs. Jingles and jangles. Absolutely. I like that. So I don't want to do it now because then, I mean I would get the bot, but then. Yeah. And then I wouldn't get. There won't be big face fair here on .netcon for that. So, yeah, we actually, some of the folks who are watching this stream, I want to say this morning, but it was yesterday morning when we were rolling with Kathleen Dollard. There were a bunch of folks that gave out gift subscriptions to random people on stream. And they got bots. Oh my gosh, that was a great. That's cool. That's awesome. Well, lovely. Yeah, we've been kind of chilling. We're glad you're here to fix the audio. Holding things down, making things happen. I saw you guys were having fun playing with the Stream Deck. We did. I bought a Stream Deck tonight. Are you kidding? Oh, that's great. I bought a mini though, so. I have a little six button. Little six button. Ema bought one too. And the question is, we want to see if we can, maybe you already know the answer. We want to create Stream Deck extension so I can F5 and F10 my code. Is that possible? So the Stream Deck, each one of the buttons you can wire up to run applications or to fire hotkeys. There it is. So that's from our friends at Elgato. So. Because I already have a HD60 and an internal PCIe card. So I figured I'll just give Elgato all my money. Absolutely, right? They've done a tremendous job with those products. I fell in love with the Stream Deck. And I've seen the tweets you guys put out there. You took screenshots of what photos of what the Stream Deck looks like that we tricked out. Pretty amazing. For .NET Conf. I really wanted to make it so that when we hand it off to you guys, when we hand it off to Javier, when we have breakfast with Beth a little bit later today. Breakfast with Beth. Da da da. Needs music. It's just, we do. We need theme music. Challenge to all of our Twitch subscribers right now. I'll give you a, I'll send you a Elgato Stream Deck. If you, whoever makes six, now I'm not gonna go all crazy with the 15. But I will send you a Stream Deck mini. If you submit to Jeff on Twitter, your, you have to make the music though, or your audio voice. And whoever Jeff picks, if anyone submits, you can win a Stream Deck mini. I will send that anywhere. Send music for Beth. Breakfast with Beth. Okay, so Beth is on in about six hours. Six hours, six hour challenge. Okay. That's a, because now that we're just giving Elgato more money. So not a, not a sponsor. Not a sponsor. Not a sponsor. No sponsor. Who are our sponsors? Well, let's find out cause we have a awesome. We've got lots of commercials. We have one, you wanna play? Commercials, fill it. Yeah, let's play. Gonna do the Azure. Let's see who's that one. Oh, I guess I'm here. Yeah, sure. Let's start with, let's talk about the Azure Functions. All right, let's do it. I love Azure Functions. Azure Functions is a serverless compute offering that enables you to run code on demand without having to explicitly provision or manage infrastructure. In this video, you'll learn how to get started developing serverless applications with Azure Functions using Visual Studio Code. If you wanna get started with Azure Functions inside of Visual Studio Code, you need to make sure that you have the Azure Functions extension installed. So I'm gonna go to install extensions, and I'm gonna search for Azure Functions. Now I'm gonna go down and select the Azure Functions extension for Visual Studio Code. Now, notice I already have it installed, but if you don't, make sure you go ahead and hit that install button. Now, once you have installed an extension, you should see a section down here for Azure, with the Azure symbol. And then if I click on Functions, it should show me all my various subscriptions that I have. And if I, for instance, open the one that says Smart Hotel, and I open the Functions, I should be able to see all of the functions that I have available inside of that specific Azure Functions app. Now, let's say I wanted to create a new functions app right here on my machine. I can hit this icon here that says Create New Project. And now I can just select where exactly I want to put this. So let's create a new folder. First, Function. I'll choose that one. Now I can choose what language I want to use. In this case, I'm gonna use C-Sharp. Now I'm gonna choose to open it in a new window. So let's close that one in the back. Now that my project is created, I'm gonna go ahead and restore the missing dependencies. Now the next thing we have to do is actually create a function inside of our empty project. So I'll open a command palette again this time. I'll type Azure Functions, and then I'll go to Create Function. I'll select that function app that we just created because that's where I wanted to go. And in this case, I want to create an HTTP triggered function. So I'll select the function trigger that I want. Now we have to actually give this function a name. I'll call this simple API. We choose the namespace. Next we can choose the access rights. I'm just gonna leave this as anonymous for now. And then within a few seconds, Visual Studio Code should have generated a function using the options that we just specified. Now if I close the terminal, we could browse through the editor and we could see the code that's available for us to use. Now what if I wanted to debug this function on my machine? Well, I could go back to the command palette and I can hit Start Debugging. And now what we're seeing here is that the Azure Functions runtime is being booted up here locally on my machine. And so in a few moments, I'll be able to run and debug this serverless application right here on my machine. Now if I go back over to the terminal, I can see the location that my actual API is living at. Let's do this. I'm gonna open up Postman. I'm gonna select this API endpoint that we wanted. And I'm also gonna set a breakpoint right here inside of my function app. Back in Postman, I'm gonna paste in the URL. I'm gonna pass in that query string that it's expecting. And I'll hit Send. Now back in Visual Studio Code, you could see that my endpoint was hit. I could continue stepping through this function and I could view the variables, the stack trace, and I could also see any exceptions that get thrown as you would expect in any regular debugging session. I'll let it go ahead and finish running. And now back in Postman, I can see my results here returned to me in the screen. If you're interested in learning more, take a look at some of these resources below. We'd love to hear any feedback you might have, so feel free to send it over. Enjoy the rest of the app they call. All right, we're back live. If the audio is still working, Jeff tells me the audio is working. Yeah, we got it. And I'm very excited because it is almost 2 a.m. here in Seattle, Washington. Oh yes, that's why we're in, this was the only hat I had with the bird on it because the early bird is here. Oh, you got it wrong. The early worm is the one that gets caught. Yeah. Yeah, that's a good one. It's kind of how that works. I don't know. Yeah, no, it wasn't that. And it's right, East Coast bird, not the Seattle bird. No, wrong bird. That's okay. Well, what do we have, what are we going on now, Jeff? Who's coming up next? Is this Jacob? Jacob, oh my gosh. So I was experimenting with Peach Pie last week on Mystery. So Peach Pie is pretty cool, right? It's compile your PHP and use it with .NET. Two of my favorite. My own is PHP and .NET. Oh, and PHP is my very first, is what I started with back then. Relic in the day, yeah. Oh, love it. So we're ready to go with Jacob. Yeah, how do we do an Emo? This is, James and Emo signing off the .NET crew over here. Follow us on Twitter at James Montemagno. And at TerraJobs. Yeah, very easy to remember. All right.