All right. Good morning, everyone. Thank you for coming back to Red Hat Developer Corner. And joining us today, Jeremy and I is Max and George. Maybe, Max, if you want to introduce yourself. Sure. Max Anderson just back from vacation learning how to use a computer again. My name is Andy and I'm co-leading Quarkus at the last couple of years. And yeah, that's me. George is O2. Yeah, so my name is George Eros or George Andrew Dacus. I work as a Suffer engineer on the Quarkus team. I've been doing that, I don't know. Probably lost track. What is it? Three or four years now? So yeah, that takes up all my time these days. Great. Well, you'll notice I have this big R on my chest because nobody on the Quarkus team has sent me a T-shirt. They sent to everyone who made a commit? Yeah, they sent a commit. Oh, okay. Okay, I get it. Hey, you guys, we can plug you. So these guys are frequently on Quarkus Insights, right? Actually, Max, you're always on Quarkus Insights, right? Oh, sometimes. Most of them. Most of them, okay. So for those who joined that think we're going to talk about open telemetry and micro-profile, we kind of had a little glitch. We're actually going to talk about unit testing today, so I hope you stick with us. And we're going to talk about the Quarkus unit testing that Jeremy's been teaching me. So we'll see how that goes. It's not in Rust, right? So why don't we jump right in? I'm going to share my screen and see what happens, right? So tell me if you can see my screen. Yes, you good? All right, so for those who are interested, Jeremy and I stuck our code up here. So this GitHub developer corner stuff, and we have a bunch of basic Quarkus unit testing stuff there. So what we're going to do today, though, is we're going to walk through a little project and look at how we can add some unit testing to that. So all we did here was we went and generated a Quarkus project to get us started. And the only thing that it's got in it so far is we added, you know, REST easy basically with Jackson, and then we added some hibernate panache to it. We created a simple database that we're going to use. We're going to do a very simple book example here, and we added some properties to get that going. But you'll notice we have a model, one entity in there, just a simple book, a repository pattern, and a service, but we don't have any resources yet to access it. So what Jeremy... Is it just me or is this screen very small? Oh, is it? Okay. Sorry. Let's figure out how to get this. Is that better? Yeah, bigger phones are better, but yeah. Is it? Okay. All right. Let me know if you can't see something so that I can... Yeah, maximize that piece. Yes? Yeah, maximize that piece. It'll be easy. This part here? Is that better? Okay. So all we're going to do here... Sorry, I'm going back here. We're going to add a resource. So Jeremy, stop me when I mess something up. So what we want to add is a book resource so that we can add, get to this code, right? Why did it do that? It never works on the... So let's add a path to this. That's it. That's all we got so far. So let's inject our service because we want to get to the service. So Jeremy likes using services. He tells me so that he can add validation to it. Is that right, Jeremy? Yeah, it's easier to test it. Okay. And what do we want to test first? Just to get all the books that we stuck in the database for the initial project? You know, I can type about 80 words a minute if I include the backspace. So what do you think? That'll work. I haven't added any testing yet. So the way I normally test is I'm going to build it and run it. And I don't do this unit testing and Rust kind of thing. So... No testing needed in Rust? No, because the compiler yells at you about every little thing. So it really makes for good code but like triples your time to product. Well, you can test in production that way too, right? Yeah, exactly. And there's no exceptions, Max. So just think about that. Nice. All right. So we're doing this live coding. So Quarkus, maybe one of you guys want to explain what live coding is? Well, so we have, in Quarkus, we call it dev mode where when you run Quarkus in dev mode, Quarkus dev or maybe Quarkus dev or Gradle Quarkus dev or you run it from the IDE, it will just run your app and then it will look for changes. Whenever a request comes in, it will check, has changes happened and then if there has, have been changes, it will compile and you get the update and restart. And it's different than like normal like reload where we only do it when it's necessary where others tend to rebuild every time there's a change. So it lets you like play around and do changes and it's only when a request comes in, you actually don't have to deal with compiler errors before you're ready for the change to happen. So yeah, that's the dev mode of, yeah, what we call live editing or accounting. Yeah, it's also awesome. It is pretty awesome because I, normally I'm wearing a C++ t-shirt and we don't do things like that there. Well, you have all the time in the world, right? Yeah, exactly. You have more time doing development. So I went ahead and pre-created a couple of tests the way I would test it in Postman. So I'm just going to send that out and sure enough, we get our four books and those four books were imported here into the database. The database is not actually, it's actually running in the dev environment now, right? Yeah, you probably, yes. Yeah. That's another feature we have in Quargers Dev Mode that you can add like, I'm not sure what you have here is Postgres or H2 or something. But if you just have a dependency. Oh, yeah. So here you see that only the prod mode is configured but in dev mode or test, there's nothing. So what Quargers says, hey, you have an added entity and you have a data source. We will create one for you in a dev service. So if you run H2, it will be starting at H2 in processed Java mode. But if you are doing like Postgres or Oracle or MySQL will actually start up a Docker container or a container using test containers. And again, this is one of the things that just magically works and you're surprised when you see it the first time because like, you normally have to, oh, we have to have a separate dev instance and configured and booted up before you run. But all that's happened, it's all managed by Quargers. Yeah. So that's the dev service. Yeah. You have Docker desktop running. Pop up your Docker desktop for a second. Everybody can go to see it. So if you haven't used Quargers dev mode before, you can see test containers as spun up and a database, which is really nice. I don't even use H2 anymore. I used to use H2 for everything. Yeah. But you can just use Postgres, right? Yeah. Yeah, there's no reason to use H2 anymore. Yeah. Well, that's good because the last time I used it was with some EAPs. Was it EAPs? A couple years ago. Yeah. So I almost never use it. Everyone uses Postgres, I think, pretty much. Oh, I was using H2. I used H2 forever for a long, long time. Oh, really? Yeah. But it was, I mean, dev mode just kind of kills it. So what? Need for it, right? For any production stuff where you're using it, like in production, you're using a real database, there's no need to. H2 has a lot of uses, like you can write in a CLI or some small thing. But for testing, you might as well just use a real thing because it's so easy now with test containers and dev services. Yeah. So Jeremy likes to test everything first. I'm going to keep blaming him because he drags me into this stuff. Yeah. So what we're going to do is, let's create a test harness for this. So what we're going to do here is add a Quarkis test. Right? And we're going to, do I need to add the test to HTTP endpoint? Yeah. I think so, right? You don't have to, but you can yet. OK. Just for completeness. And the cool thing, Quarkis test in the background is going to spin up another instance of Quarkis running on a different set of ports. Right? So you don't have to pull your running server. And these tests are going to run in the background while you're coding. It's a really, really nice feedback. Yeah. So, and then this is, yeah, it just works. And, you know, one of the things that's nice is like Quarkis is very much focused on performance and using a little resource as possible. And that is for production and the test runs. In Dev mode, we are assuming you have a laptop or machine that has a bit more room.  And then a separate one for the test. So you can, you know, you don't step on, step on each other's toes. So while we're talking, I'm starting to write this test. And I know this part. Right? Rest assured and content type and content type JSON. So what is this bit here that I'm going to start adding? Yes. Also, if you're following along and you haven't used rest assured before, it's bundled with, or it comes with Quarkis out of the gate. If you're using any of the rest easy stuff, which is any of the web stuff, it's going to pull in this library rest assured, which is a really great library that makes it super easy to test any kind of any kind of web things you're doing, you know, all your crud stuff. And you got a static import. So you can just use given. And it's a really nice API for creating tests. And hand-pressed matches are pulled in too. So the matches are really nice. So anybody read the three-body problem yet? The science fiction book? Not that I recall. So I wanted to read these books by Zix and Lou. I think that's how you pronounce that. It's called The Three-Body Problem. Before Netflix made a series out of it and ruined it. So it's really pretty good. It's a pretty good science fiction series. So anyway, so what I have here now, and I'm going to go ahead and talk about it. So anyway, so what I have here now is what I'm hoping is the exact same thing that I'm doing here in Postman. So I run this and I get my titles. And I want to get all the books back. And I'm just testing that it has these authors in it. That looks good, Jeremy. You just need a semicolon. That's true. Oh, you guys in your semicons. Okay. So in C++, the curly brace goes here. How many times have we had arguments over that? So let's run this test and see what happens. This is the part where I get a lot of red or something on the screen. No, it ran. Wow, that's great. Look how easy that was. Yeah, no errors, no exceptions. That's right. So let's add some other stuff here and for time's sake. Maybe you want to go and add an error to the test just to check that you actually are running the right thing. Oh, I'm really good at adding errors to things. So let's never trust a test unless you've seen it fail. Never trust a test unless you've seen it fail. All right. What if I put a misspelling in here? Hey, there you go. And what kind of cool error message did we get out here? So we said, we got a collection back containing the right names. But, you know, our comparison here didn't have this section in it, right? Yeah. Yeah, I didn't tell you that the key was different, but that you didn't get. I mean, no, no, no. The error message makes sense from a rest assured perspective because it's looking for a key. Yes. Yes. Can you see that? Or is it too small? It's too small. Okay. It's too small. All right. We'll run it again just to make sure that it worked. All right. All right. Cool. All right. All right. Cool. Perfect. All right. Let's add another method here. So let's do the rest of the crowd operations, right? So let's do a post. I love IntelliJ or basically all the JetBrains tools. You guys use VS Code. What do you guys use normally? Whatever works that week. But yeah. Okay. VS Code IntelliJ.  No. About it's stealing passwords? No. Oh, yeah. Yeah. What's that all about? I didn't hear it either. There's some kind of, you'd have to look it up, but there's some kind of issue where you can steal passwords from your VS Code environment. So when you're logging into things with VS Code, you could potentially be giving your passwords to somebody. That's on all VS Code environment. I don't know if that works on Mac, Windows, or everything else, or it's just on Windows. I just looked it up. Extensions can be malicious. Don't trust anything you download from Instance. Anything has a plug-in. So apparently the way that the application works, the extension can list in on your type again, the password to another extension. So yeah. So I'm going to add a put here also. So we want to create something, and now we want to update it. All right. So let's use this good old-fashioned try catch, because Rob writes a lot of stuff with errors in it, and the compiler is not going to stop me here. Invalid parameter for exception. Yeah. Sorry, you guys have to watch this. I know you're in this all day, but... Oh, it looks good. Okay. So we just added this code. I'm still running. So we should be able to go over to Postman and actually run this, right? So we should be able to do a create. So I'm going to create one. And sure enough, I added it. And we want to update that from... Well, we got back to five, right? So we're going to modify that. We're going to say change more of the worlds to invisible man, because we did the book ID, the book. So let's test this. Let's actually write a test for it. What do you think? See what's happening here. Sounds like a good thing. That sounds like a good thing, right? Writing extra tests for debugging is an underrated way of debugging things instead of using... All right. So what I really want to do is create and an update, right? All right. So we're going to create function. Next, what do you think? All right. Guys help me out here where I'm messing up something. What are you trying to say without a transaction? Yeah, I'm going to do this create here. Let's create a different one. So William Gibson is another author that I like. So let's do that. Anybody ever heard of this book by William Gibson? Neuromancer? Yeah, right there. Yeah, I started with genre, right? So that whole genre with, you know, what do they call it? Some kind of techno punk thing, right? I said that's cyberpunk. There you go. No, I'm not a fiction fan myself. Oh, what do you usually read? Nonfiction. I like what? Ah, history, politics, stuff like that. Ah, okay. So right next to me on my desk here, I have a nonfiction book. I don't know if you can see it on the screen. That won't put you to sleep at night. I can't make out the title. Oh, you can't? It's a history of the Sasanian Empire. Oh, okay. Excellent. For me, it looks like a good night. It was a lullaby story. Is that, to get your kid, you don't try good night moon. You go straight to the history of the Sasanian Empire. Yeah. But you know, I just remember it was like a Miga game. Was it really? I just remember the romance. I didn't, I didn't read the book. First I learned it from a game. I believe it's like a Miga or something. It was like a long time ago. I think probably the last like fiction I read was probably like some Scandinavian murder stories, stuff like that. Really popular around here. Yeah. I have to alternate between fiction and nonfiction. But the nonfictionary doesn't necessarily make me look smart. Doesn't necessarily. Sorry. Didn't get you. Doesn't necessarily make me look smart. Like football packets. So let's see if we, you know what? I'm thinking that I'm going to have to write a test here for, to test. So we actually have a test that we did to create. But what about testing it with a, what would it help if I put a new in there? So let's actually test that. So this should work by creating a title with an author. So we're, that's different. So we're going to do Neuromanswer by William Gibson. And then we're going to look that up by title. I just looked it up. It was 988. I'm feeling old now. Was it really? 88? Yeah. Is that like it? The game came out in 988. Oh, the game came out 988. Okay. Yeah, the game came out from 84. All right. What are your recommendations on how to make the test fail first? Since we want it to fail, right? It just assert a wrong, you know, it assert something you should be wrong. Yeah, it's code. Yeah. How's that? Yeah, sure. Yeah, just something to make it fail. See, now you've got a problem, right? Yeah. That test doesn't fail. It's all good. Yeah. Yeah. Now why? Test in production. Ship it. Ship it. Now is this, is this going to run different? Is this going to run different if I, if I rebuild it? So I stopped the live code and rebuilt it? No, it shouldn't make a difference. It should be the same. It should be the same. So why do we think that that's going to work there? Any ideas? Jeremy? Anything? No, I just run it. Well, you don't, you don't, so you do, you do assert. Yeah. Yeah, right. So I did an assert here. We got a 201 back. Neuromancer. We did a query. Yes. We shouldn't get the title back though. That should be. Okay. I see what the, you're, you're not performing a get anywhere. Giving content type, pram, then. Yeah. You need to say get. Yeah. Yeah. There's no when get then. There's straight then. Yeah. The rest assured DSL doesn't save you from that. That's happened to me a few times. So you win dot get. And that should be another thing.  I think it's a really great library. The JSON path I found it took me a while to get used to their JSON implementation when you're really complicated stuff. Yeah. That's no fun. Yeah. I don't have a really good workaround for that yet. But. Man, neither do I. Now we failed. Actual zero. Cause we don't have anything in the gap. Right. So what we really want is the ID, right? That just got generated. Yeah. I think the used. Yeah. Use the, the ideas, the path. Yeah. But we, but we, we really wanted was this query. Right. So do we not have a, we have the ID, but we didn't actually, we have a query param here. So what do you guys think put down the spot? Well, what does book service. Yeah. Find actually do. So book service dot fine. We can pass it a query and do the repository find all. And we're going to do a like, whatever the query is. I don't see how is, how does the query represent like name. Or whatever title is. Okay. Sorry. The title is on. It's already in there. Okay. Got it. Gotcha. So what we need is the resource that we need to fix this. Right. No, I think that one. I mean, if the database is populated properly, that's, that should work. Do we need to fix this? Okay. So how about, Okay. Yeah. Neuromancer, blah, blah, blah. Okay. But hold on. So you're running. Okay. You have to get on. Okay. I see what's going on. You basically the way the test is written now, you have no guarantee that your get this, this get book with query prime is running before create. And actually, if you look at what IntelliJ is doing, it's running that one before the create. So what do you need to do this? Can we add order? Yes, you can, but you need to add an annotation to, to the test itself where you say, I think it's the annotations called like method order or something like that. Yeah. Method. Yeah. I got it. How about this? Test method order. There you go. Yeah. And then you need the, in here, blah, blah. That's not it. So like, I don't remember what the name is like, you know, order annotation or something like that. Yeah. So we actually need to add, five test method order. Yeah. Okay. So it's called method order dot. Order annotation. That class. Yeah. And then we can add this as a second order. Yeah. You know, so you added one to create in two, two. Yeah. Okay. So that should probably work. Well, I'm glad we got the experts on here, Jeremy. We're going to watch this later. We're going to watch this, fixing this for a long time, right? Yeah. Well, I mean, I've looked at so many user provided applications where they're like, this isn't working. Some, it's Quarkus problem. Yeah. So, I've learned to spot things like this. It's not a Quarkus problem. It's a user error problem. Well, it sometimes is. I mean, so let's, let's, let's add the delete. And because I'm, I'm kind of running out of time. I'll, copy the lead in here. How's that? So, because you guys don't want to watch me write that. So what we're going to do is we're going to say, deleted by ID. So what we did was, we did a test get, we did a test post to create something. We did an update to it. And we did a delete, right? So if we run this, we should be able to test all those things in postman. All right. So we did all that stuff in postman, but we don't like postman anymore. So we're going to do is we're going to add this. Delete to our test. Right. That makes sense. Okay. So, and because we just tested this with a particular order. Test normally need to run out of order, but if we're going to do something. This, we're going to add some order to it. And we're going to say void, remove, because we don't want to just call it delete. Given content type application. We'll do that. And then we'll say, when. Delete. You know, too fast on the tab, right? And we think it's probably number five, because we didn't, because we only had four when we inserted into the database. Then that is code. And what's the status code on a delete. To go for, right? So now we should be able to create it. Make sure that it's actually there. And delete it all in order. Voila. It looks good. All right. So, but what if I want to test this in a. In the container. Is that an integration test? That should be pretty easy in. Right. Sorry, you want to do what? Kind of an integration test. Okay. Yeah. So. Yes. We're an IT on the end. Do we get. Because integration test. Yeah. Like that. Should be that easy. Now can I run that in live mode? No. Okay. So I have to stop this. You need to package the application for this. But if you, you can try and run it. I mean, if you try and run it now. I think the error message. Should be fairly clear. Say that. You haven't. Package the application. And therefore you can't actually execute this type of test. Against it. And it might be worth mentioning a different right. Like. The, the, the, the rest of short testing is actually testing the end point. Which is, you consider it like a black box testing, but it is still running in like dev mode and.  So things are easy. When you run the. Integration tests. The intent is to run like. A fully package application on its own standalone and tested from fully outside. Not that you can do with a package jar. In a container or also a native binary. Right. Because a native binary cut. Tests in, in this dev mode. Also not a jar. So that's, that's the reason why we have this separation. So I got out of the dev mode. I did a build. I'm going to run it here just to see what's going to happen. And I'm going to put. So it's going to create a bunch of stuff here in Docker. What's going on there. So it's the same. Okay. So I think what. This is going to go away. Right. Okay. Let's see what's going on here. Yeah, well it starts test container. I mean, it does the same. Just right. So what I would really need to do is package this up. And then. Then run this test. Right. How about, how about try, try like a maven clean first and then run this. And that, that should fail. Because if you've, if you've been, if you built it prior, this would, this would work. Okay. So now I'll just try like, yeah, running this. Yeah. Yeah. Okay. Yeah. And the error message should tell you that you haven't packaged the application. I mean, yeah. If you go down, let's see what it's saying. If I can't make it out. Oh, I'm sorry. Yeah. Make sure the test is run after the course application has been built. Yeah. Okay. That's right. Yeah. As Max said, basically the idea is that if you're going to run the application. Yeah. As Max said, basically the idea is that this is a process of testing a running application outside of the application process itself. Right. So this is just like, it's like running postman against a running against the Quark's application. Only in this case, the test itself also starts the application, whether that's a container or Java, Java jar or a native binary. It doesn't matter. So what if I, if I want to add something to look at the test coverage, we can simply add Jacoco to this. Right. Yeah. That should work for the Quarkus test. Yeah. Well, yeah. You have to, with one addition to your palm, it'll also work for anything else. Right. Yeah. The first time I did that because I have a mix of Quarkus tests, right? So stuff in isolation. I remember like being very disappointed for a while that I was getting zero coverage on things that I knew I had test coverage for it. But isn't it?  They're Jeremy. It's code coverage. Just code coverage. So I, all I did was add this to the palm. And did you see how I accidentally started trouble the other day on the, on the app.  No comment. People like. I know.  It was just a comparison between Maven and Gradle. And it started this whole religious. I really like Gradle as long as it's important. Say what? I say I really like Gradle as long as I don't have to support it. So what we were. What we ran here was all I did was I added you go go to the palm. And after I ran the test, I got this at the bottom here. So I'm going to cut and paste that into my browser and see what I get. Oh, well, I got a whole directory there. Right. So we'll always go to the index HTML. So what am I seeing here? This is. This is. This is. This is. So what am I seeing here? This is. All the stuff that just got run. So the model got hit. It's a lot of red. A lot of red, right? Because I didn't actually run a test for everything. Right. So we did the resource, but we only hit a portion of the resources. Right. To get to create the remove. Okay. But I can see my test coverage. And the only thing I had to do is add something to the file. That's pretty slick. I like that. Maybe you want to show it a continuous testing to. Talking to her. Yes.  We could do this from the terminal, right? So. Yes. We can name in cork is dev. Right. So we could do. Maybe. Cork is dev. But if I'm a pointy clicky kind of person, I can do it over here and just. Find it. Run it. Right. Yeah. And then you start up. It was just say something like you see in the lower part, it says. Test post. So normally cork is a startup being like, no, like normal. You can do you can run the, let's call the play mode. A demo. But if you go scroll down to test. The pause is like resume testing. So if you click are. A pressure. I did. It starts running the test in the background. All my tests just got run. Yeah. You know, it's green. Now you can go into the test before and just like change the, the get. Whatever the test where we're feeling. How do I see which one's failing? Yeah. Well, they all green. So just fix. Green. Yes. Change something like. So. Right. Six right. Because we didn't do that. Yeah. Okay. And then it should be picking up in the low. Yeah. Yeah. Broke it. Now fix it. It'll actually. It'll run super fast too. Yeah. So what it does is so that the, this actually the fun story here is like when we dipped corkers first. Oh, sorry. The first version of corkers. We had death mode. We didn't have a continuous testing. And then 50% of the crowd. You know, users say, Hey, this is awesome. We can do all the experimentation. And then the other part said, Hey, I can't do testing. That's why I have to do testing first. So we came up with this proposal that we want to do continuous testing.  But you also get feedback immediately. If you break your tests. So it kind of allows you to have fun while also doing test driven development. And what it does is even if you had a lot of tests, it keeps track of what code paths are being affected. So if you have a hundred tests, it will should only run the ones that are that failed or the ones that are affected. Like it tries to be smart on what running. So it doesn't run the full test suite all the time. It can also tweak and configure it to be a subset or whatever, but it's trying to be smart. So it's pretty nice. Of course, if you're used to not having tests, then this is not interesting, but this might want you to have tests because now it's not a big problem. So I want to add, I'm going to add one more thing and then turn it over to Jeremy because I, I like to add, you know, I come from a world where everything's a printf in order to debug something, which is horrifying, right? But I learned this cool thing that you guys added here where we could get callbacks. And while I'm adding this, maybe you want to talk about what callbacks are, Jeremy or somebody. What are you adding a callback for? I'm just going to add a callback that says what test methods I'm executing because I couldn't actually see all that down in the terminal there. Yeah, so this is usually used for like integration with other stuff. But yeah, nothing prevents you from like adding it to the application itself. But yeah, so this is similar to G units before each annotation. But I think this provides you a little more information. A little more contextual information that is. All right, so because I like to print stuff out, we're going to do this. I remember the days when we didn't even have unit, we just did assertions inside your code. Sounds like fun. That was, you know, 25 years ago, but it was just chill my age here. You guys really, this is really great. I mean, if you come from most people nowadays, you know, they're, they're looking at stuff and going, oh, this is just, you know, the way it should be, right? You know what you guys have added. But those of us that have been around a long time and had to do things, you know, the hard way, you know, walking uphill in the snow both ways, kind of thing. Did I put them right? Makes you think what we'll, what we'll be saying in the next 20 years. Yeah, kind of, you know, what, what, I mean, this is, this is really good stuff.  That may be coming, who knows, right? Yeah. Finally, a double, a double colon. That's my world. That's what C++ uses for, what, virtual calls or something like that. Yeah, everything. All right. Now we got to add something in here, though, in this meta-imp package, right? Yes. Yeah, it's not picked up automatically. Yeah, so that's, yeah, it's a little manual. Service, right? Yeah, meta-imp, yeah, under meta-imp service. Oh, you know what, went under dot resource. Yeah, that's what Retellogy does that automatically. Yeah, so you have to move that. I have to move that, right? Yeah. Move directory. God, refactoring is so nice. So I need a file name here. The file name is the name of the class you're implementing, basically. Yeah, I don't like it. The cork is test before callback. Yeah, so I need a file name. So let's add a file. io.corkus.test.junit.callback.corkus-test before each callback, callback. Now I can put the name of the thing in there, right? Yeah, your implementation. Acme dot this thing. Yeah, exactly. That should be good with that, right? IntelliJ seems to not like it. I don't know why. Is it telling you why? No service provider. It doesn't make sense there. Let's refresh that. Let's just run the test and see what happens. Yeah. It might be just some IntelliJ thing. I think I saw it. So we said executing and then the test. And then I printed off the annotations that were on that test. Nice. Very nice. I like that. Now I can see what's going on from us. So we can enrich this in a number of different ways, right? There's a bunch of different callback types. I like that. That's cool. Especially if I'm integrating, I've written stuff where I've had to integrate with downstream services that you paid for every time. And even when you hit it in test. So Jeremy's going to talk about how we're going to mock some of that out. And I know we're right at the top of the hour. I apologize if you guys have to jump or something, but it would be great if you could stick around maybe a little bit longer for Jeremy. You want to take over? Sure. I'll go really fast. Yeah. This is what happens when you stick somebody who's not a native Java developer in Quarkus. But what I'd like to say is look how easy that was. Can you guys see my window? You can now, yeah. Yep. All right, now you've got to make it bigger. Why is that? I'm happy you liked it. I'm looking forward to your first contributions. You can have a new shirt next year.  All right, so the first thing I want to show, I'm actually going to start with Wiremock because somebody asked to start with Wiremock. So I've got an app. I've got Quarkus running in Dev mode right here. And I have since this weekend, the Premier League starts, I thought we would call an API and I'm calling into an API to get Premier League fixtures, fixtures. And so Saturday, we can see we've got the results are getting back. I'm making an API call. This is to API-football. And we've got, it's in Turfmore, right? So it's Burnley and Manchester City. So let's come over here. Let's look at what this application is doing. We looked a little bit at this before. So how's that? See that pretty well? This is pretty basic, right? Our path is right there, PL fixtures. I have a REST client API football service. And I'm really just returning that as a pass through, right? I'm passing in the parameters that the API wants. If you want to look at what the Quarkus REST client looks like. Here we go. I've got a couple of things going on here. They require this configuration key. I've wired up where this URL is inside my application properties. This is a custom header that has my key. I've added that on the command line so that I don't accidentally commit that into source control, which I do kind of regularly and then regenerate my key anyway. And then I have get fixtures by date. This is just an interface, right? So Quarkus is going to implement this for you. I've got all these query prams. This all looks pretty normal if you're used to using any of the REST easy stuff. So the way we test this stuff, I want to use WireMock. And what WireMock allows me to do is to spin up a Java server that's going to mock out my response and lets me control that response. So I don't have to ping against this API and pay for API calls while I'm doing my testing and development. So this is a Quarkus test resource lifecycle manager. So I guess it introduced two things. What a Quarkus test resource lifecycle manager does is this allows us to annotate one of our classes with this. Where's my class? If you have both, we're really standing test. So I can annotate the test with that. And it's going to start up another version of Quarkus, right? So we mentioned before that in the background, there's one version of Quarkus running, putting a test resource around it. The lifecycle is going to start up a second version. But it also means that it's going to make whatever happens there is going to be available here. So I've got this, my WireMock proxy. WireMock server, we haven't used this. It's a really great utility. It's got a website, pretty good docs. We start up the server here. I'm listening on port 8089. And then what I'm doing is I'm, what I'm doing here is I am stubbing this out. So I'm first, I'm going to intercept everything. And then I'm going to return a call proxy to, you know, the API service that I'm using, right? And then when I get a specific URL, I'm not going to return that. I'm going to return a canned response that I've got here. And this is my canned response. The way I'm going to know this is that we've changed Burn, we've changed Turfmoor to Main Road, right? So we're going to get the wrong answer back. But as long as that's what I'm expecting, then that will be correct. I mentioned that we've got Quarkus, Quarkus is running in the background here. Let's, and then we, the method, the life cycle has two methods, start and stop. So it cleans that up. So our test here, where's that really extending? API football service test. And this, I'm just testing. I'm just testing that my REST client works. So we can run this thing. Let's run this. I passed. So again, I'm expecting, I'm expecting the wrong thing. So let's put this in. We were talking about earlier. We always want to see, make sure our tests, you know, are accurate.  I'm not going to get back the real number. I'm not, I got back Main Road instead, right? And we noticed like, so Quarkus in the background, hit R for resume testing, right?  Jeremy, we lost your screen. Okay. Let's go back to that. Can you guys see it now? No. All right. Better. It's telling me that I'm sharing. All right. Let me, can you guys see it now or no? No. No. All right. Sharing. Share again. Screen one. Share. I got a little message that says I'm sharing. All right. There we go. So we changed that back and it's already passed the test. So that's how I test the REST client, right? I've mocked that out. I've intercepted this call. You can also just mock. And this is also we'll begin looking at mocks. So now I want to test my REST endpoint, right? The one that we're looking at that I'm looking at here. So in that case, I don't have to need to round trip that. I can just mock the API football service itself, right? So I can inject mock, tell it that it's a REST client.  And I've got my own method for that, right? And so this is what I'm returning. So I'm just going to return this object again with the wrong. I'm going to turn it with the wrong venue, right? And I mentioned earlier the one kind of gripe I have around REST easy is that I think the JSON path is a little bit wonky, but you can get through it once you start looking at how it comes back. But it didn't work exactly the way. Maybe it's because I spent a lot of time working with Vertex, which I think has a really, really nice JSON implementation. So I found it really a little bit odd. What I'm going to do here is in this case, this is also another version for REST easy. I can also get the response out, and then I can just get the JSON out of the response, right? So I get responses string and get the JSON out and then parse through my JSON because the JSON I'm getting back looks just like this. So it's a little bit complicated here. Where's my utilities, test values? So this is the JSON I'm getting back, right? So it's a good bit of JSON, right? Nested stuff. I've got a raise in here. So some decent work has to pop through here. So let's run this thing. We can see the mock, and so we're working there. And again, this time I don't have to mock anything out. I just tell it to return whatever I tell it to, right? So there's two different ways you can do that. We can do WireMock when we actually want to proxy to something, or we can, when we want to test the REST client itself, we can use WireMock. Otherwise, we can just create a mock. So let's look at a couple other mocks here. Stop Quarkus there, hop over to this project. So in this case, I have got, let's Quarkus Dev, fire up Quarkus here. Let's take a look at this UI I've got. It's a local host. I've got a local group for Premier League Pictures. We're going to do hello, so I've got some hello. And now I'm returning some random hellos, right? So hello from a number of different languages, right? I've also got a local host, 8080, quote. So we get a quote, right? And we've got some random quotes, right? So we can pass back a few quotes. These are all coming back from the dude, but there are quotes from a few different authors. There's Walter, right? So we have a few different quotes. So for testing this, two different things we can look at testing here. The way that the rest endpoint looks, let's close this. The rest endpoint looks like this. At hello, I have two different services. I have a greeting service and a quote service. They're both fundamentally the same. I just have a list of greetings here in memory. You can see that. And I'm just returning a random one of those things. And then quotes are the same thing, right? So I've got this list of quotes here, and I'm just returning a random quote, right? So I return in hello, I return a random greeting, and then in quote, I just format the greeting, the quote object. So it comes back like that. So tests we're going to do here. The first thing I want to test is... Now, I've got, notice down here, my quote test, I'm going to call, I'm going to get one of these random quotes back. And this is another thing I mentioned, the Hamcrest matches. This is baked into Rest Easy. So I've got this Rest Easy given when I get quote, and I can say contains any of dude, mod, or Walter, who are the three authors of these potential quotes. So basically, no matter what quote I get, I'm going to get one of these authors, and I'm just making sure that one of these comes back correctly. Hello endpoint, I'm getting back random greeting, which is not part of my greeting service. I have a mock greeting service here. I have annotated it with mock, it's in my test directory. So Quarkus' automatic, or Quarkus' test, is going to automatically substitute my greeting service with this object everywhere in my test. It's good and bad, right? So one, every single test I run, it's going to use this instead. So I'm always going to get back this mock, this random greeting service, right? Whereas in this case, I'm going to get, I'm calling the actual object. So I can run that, and this will pass, right? Because I'm going to get back this random greeting, which is not one of the greetings in my actual resource. Another way we can mock things out is we can... So in this case, I'm going to create my, I'm going to inject my mock directly into the test. And what this means is I'm only going to have a mock of quotes service here inside of this test. So my other test was using the regular quotes service. I was getting back a random quote from one of those three actual people. Now, this one is going to use the annotated mock object, because that's for every single test case. And in this case, I'm going to need to train my quote service, right?  And that's the stranger. It's not Maude or the dude or Walter. And so this case, I will get my quote back here. Right? So run that. And we'll get that quote. It's two different... So there's two different ways, right? If you annotate a beam with mock like this, it's going to be injected across every single test that you have, right? So you want to do that if you know globally, I don't want to use this thing, right? And then if you inject a mock inside of your actual class, you get more control, right? So sometimes I want to use a real thing, sometimes I don't. This is more obvious, I think, if we start looking at panache, right? So we'll be looking at some database stuff. Look at the way you mock out panache. So let's quickly, we will jump over to panache test. So in this, I have a... two of these things, but let's start this up. That's it. That started. So what Quarters Testing Panache does, I have two different greeting resources, which are two different ways we can use panache to store stuff in the database. The first one is an active record greeting, which is going to use the active record pattern. It means that I have a... In this case, I have a get where I'm saying hello, but I pass in a name. If the name is null, I just return hello. If I have a name on the format, then I create a greeting object, persisted in the database, and then return hello name. And then I have a list all, where I can call greeting list all. Panache makes it really, really easy to do this. So my entity, if you haven't seen panache before, extends panache entity. It gives me all these kind of methods that I just called, like list all here or persist. I can also do all kinds of querying and stuff. So let's take a look really quick here. Let's say hello. And we just have hello, but then I can say... So let's say hello and let's say all. Let's see if I've got... And I've stored that in the database, right? But when I want to go to test this, let's say I want to test my active record greeting test. So one thing we can do, and this is... A lot of times when we're testing, and traditionally I used to do a lot of this stuff. I mentioned I used to use H2, used to do a lot of this. I'm actually going to populate something in the database. We can do this in our setup method. It makes this really easy. Panache makes this really easy to do. And so in this case, when I call this endpoint, I'm going to get...  That's expected functionality. And when I call hello all, I'm going to actually get one greeting because I've put one in the database, right? So I'm physically calling the database. This is really an integration test, right? But there's going to be one in the... There's going to be a greeting in the database. So when this test runs, I'm going to come back with Christopher, right? So Christopher Robin got put here in the database. Yep. Now, you don't really need to do that with Panache. And I think it's sort of... You're really doing an integration test. You don't want to test Panache's functionality. Red Hat wrote that and it's going to work. What you want to do is mock out your object, right? So now I have a different greeting resource test. And in this case, I'm going to mock out my greeting class. And I'm going to say, when we call list all, then return these three greetings. So then when I call this method, which is my front-end hello all method, body contains string. I'm only testing for one, but I can put contains... I can do multiple contained strings. And have a test for all three of these. The other thing, there's default values for all of these. So I'm not actually putting these in the database, right? I'm just mocking this object out. And it's going to say, I've got three of these things. But then if I call something like count, which is going to tell me how many are in the database, it's going to give me the default number of zero. And there isn't actually anything in the database. If I wanted to see what was actually in the database, I can mock the class. I can tell it to return three objects when it's called. And then I can tell it to call the real method, right? So don't mock out this method. Just mock out one of the methods I want to use. So this time, when I call hello all, I'm going to get one thing back because I'm putting one thing in the database, right? So I have one greeting in the database, which is Christopher. I've mocked this out. I'm not going to get Christopher. I'll get Poo, Tigger, and Eel are here. But I'll have one thing in the database. And I'm going really fast. So if this doesn't make sense, shout out, questions, yell. What's the difference between a spy and a mock? So a spy is just going to tell you that something got called multiple times, right? Or a number of times, right? So where's a spy? I have a mocker. This is a different spy.  And what it's going to do is just say verify that greeting service was called one time, right? Because I know I'm expecting, I'm really testing my rest endpoint here. And I just want to know that the rest endpoint calls the appropriate class one time. I don't like hero comes back. So that's what we use a spy for. And then one last quick thing we'll show how to test Kafka because this is really useful and this is a really great piece of small rye reactive messaging. So inside of my Kafka test, I have a Hello Kafka resource. And this is a pretty simple resource. I'm listening here. This is reactive messaging. I'm listening to a Kafka topic called Hello in. And I'm publishing to a topic called Hello out. My method is called on Hello in. And what it's doing is it's taking the Hello message and translating it to an uppercase and returning it, right? Super, super simple.  I used to before the in-memory, before I found the in-memory connector, I used to use test containers to spin up a whole Kafka environment. That was pretty painful. This is really, really nice. So what we do now is I mentioned before we have this test resource. So I'm going to create a test resource. Yeah, I think this is awesome. I used to spin everything up in Docker Compose, the database in Kafka. And with Quarkus, you can just do it all right there. You don't have to, you can if you want to, but I don't have to put it all in Docker Compose anymore. Nope. So I'm implementing my test resource lifecycle manager. So I'm starting and stopping. And what I'm starting is an in-memory connector. And I'm switching incoming and outgoing channels. So I'm switching my incoming channels, hello in and the outgoing channels to hello out. So what this is going to do is it's essentially going to proxy or it's going to switch out the implementation. So I'm not going to fire anything off to Kafka. I'm going to fire it off to this in-memory connector. And then my test is right here. And my test, I've got my Kafka resource, right? So I'm going to have access to any of those objects. I'm going to inject my in-memory connector. And I'm going to get a sync. And then I'm going to send this in to my source. I'm going to say hi there. And then I'm going to expect this to come back in caps, right? So my sync is going to receive and it's going to, I'm going to get the payload. So the receive, get the first thing that I receive and get the payload. So when I run this test, and there are a lot of other things we can do with, with the received, right? So we can do all kinds of things that say, you know, hello, we can stream things, you know, we can loop through all of this stuff, right? So there's a lot of, a lot of things we can, a lot, a lot more things we can do than just get the payload, right? But it allows us to test really, really easy. So if you're using Kafka in your apps, it's a super simple, easy way to test Kafka. And, you know, I don't think, I think we're pretty well over. So we've taken everybody's time. So George, I know you've got to leave any closing thoughts from the Quarkus team. No, this is a great summary. The only thing I do have, like you might want to show in like a follow-up episode or something like that, there's this new mode. There was new testing mode that was released with Quarkus 3.2. We call it the Quarkus component test, I think. I have one of those. Oh, okay, cool. We didn't look at it. We didn't look at it. It's brand new. It's brand new. So basically, yeah, we're just like soliciting feedback from that because it's a very new thing. Like we have some ideas like where people might want to use it, but we really want to see in practice, like if it's useful or not.   You know, how easy it was to get started. I think we demonstrated that, you know, Quarkus just amazingly removes a lot of complexity from you having to get going. It just makes life really simple. That's what I really enjoy about it. And then we went into some more of the more complex stuff with the mocking and the wire mocking that Jeremy did. And I think the Kafka and the database stuff with Pinoche was, you know, that takes us further. And you've got, oh, and you've got a component test. So we can close out with the component test. Yeah, so here's the component test. So what this does, I've got two services here, a greeting service and a tumeness service. We both ended up with some CS Lewis references this time. We didn't practice that. We did not coordinate our CS Lewis. So the base, actually I should, basic greeting. So the method, I don't need that. Yeah. What do you get going on there? That commits for that. So the component test, I have a greeting service. If I go to my greeting service, it has a tumeness service and it calls this tumeness service on greeting from tumeness. It just calls this tumeness service quote. I mean, instead of method, there's again, just some random quotes that Mr. Tumnus says from the line in which in the wardrobe, right? And we just get one of these things. So my greeting service is going to get one of those back. My greeting resource test. Not that one. This is a component test. So we mentioned in a Quarkus test, we're spinning up all of Quarkus. In the Quarkus component test, we are not spinning up all of Quarkus. We're only spinning up the Quarkus CDI container, right? ARC. So I have mocked out my tumeness service. And instead of returning one of the three actual options, I'm going to say, allow me to introduce myself. My name is Tumnus. And this way, the test is going to run even faster. Let's just give it a quick run here. And so it seems to me, and correct me if I'm wrong, George, but if you look, yes, it was super fast. I barely even got the talk while that ran. And it seems to me like that's essentially, if I know that I'm not relying on anything other than CDI, just a faster, quicker feedback loop takes even less time. Is that the idea behind doing this? Yeah. So we had a few people saying like, yeah, I don't want to start like the web layer. I don't want to start the database layer. I don't want to start the Kafka layer. I just want to test like my, let's say business logic. So yeah, that was the idea behind this whole thing. Yeah. I'll run it again just to see how it's thinking. Actually, let's say I have Quarkus running in the background. So let's break this. Let's do this. So howdy is not probably something that Pawn would say, right? Next time we have George on, I'll get a list of books that I have that are more history. All right. So we broke that. Am I still failing? Come on. It's a provider not found. Oh, well. It's what I get for grabbing the brand new feature. Yeah. I don't think it's the feature that broke it. Yeah. All right. That's what I get for it, right? I'm not used to having to know what happens when it goes wrong. All right. That's not right. But anyway, if you look again, it is super, super fast to run this test. Like it's over instantaneously, right? So there you go. Like, you know, you're not putting up all Quarkus. All right. Well, thank you very much, George, for joining us. If you see Max. Thank you. Let him know. I'll text him later. Thanks, Jeremy, for actually walking me through all the Quarkus testing for the novicec part there. And hopefully people learned a lot today. We'll see you next month. Thank you again for joining us. Bye. Thanks.


This is amazing, guys. Appreciate you being here. We'll be starting in just a moment. Look at all this Southwest, East Coast, Midwest from all over New Jersey, Missouri. Awesome. There's so much synergy in the room. I'm seeing a lot of people who work in the same area. So as you're coming in, if you're just joining us, we're talking about what we do, who we serve, something about our nonprofit. We would love to know. And I'm gonna get ready to start because we value your time and our time goes by so fast. So hi, thank you for joining our webinar today. Today we're gonna be talking about chat GPT prompts for grant writing, fundraising and marketing. This is gonna be so good. I promise you it's gonna be good. But let's talk about how we can engage today. As you know, we are recording the webinar. It will be available within 40 hours. You may get it tomorrow. So look for that. Please use the Q&A to type your question because there's like over 1,000 people registered for this webinar. So we probably missed your question in the chat. So use the Q&A feature right at the bottom of your screen and type your question. We'll try to get to as many as possible. Again, we're gonna email this within 48 hours. If you need the closed caption right at the bottom of your screen, you'll see CC button, click on that and you'll be able to use the closed caption and you'll be able to watch us on a repay up on YouTube with a closed caption as well. I want to get ready to move out of the way. But before I do, I wanna talk about Quad. I don't know if you've heard of Quad. It's so exciting here. This is a way you collaborate with organizations and industry leaders in the nonprofit sector and share best practice and experience. It's a membership community. And on top of this great membership community, 10 members of your nonprofit can use our courses. I don't know if you've taken any of our courses, but they're awesome. But you can allow 10 members in your organizations to take the courses for one price. There's so many other exclusive events. So I'm gonna put the link to Quad in the chat. So make sure you check that out in a moment. I'm gonna move all the way and go ahead to introduce our speakers. They're probably, you'll learn more about themselves in just a moment. But I'm going to introduce the ladies first, Ms. Lisa quickly. You have probably seen her on the webinar previously, but she is, I wanna say a member of Catwork. But Lisa has been in the nonprofit sector for over 10 years and she's worked with thousands of people in the nonprofit sector. Tariq, you're gonna learn so much from him. He's gonna be your AI prompt engineer today and you will see him going through this AI and chat GBT so fast. Just remember, you're gonna get this on the replay. I'm gonna move all the way because I feel like I'm talking too much. Over to you, Lisa. Thank you for being here. Oh, thank you. Thanks everybody for being here. I am Lisa Quigley. I'm the director of Account Strategy for TAP Network. TAP Network is a mission-based digital marketing company. It is a, it was founded in Delaware, but we are a global community. So again, thank you for having me here. It's wonderful to be able to chat with all of you about chat, GBT and AI. So I want you all to imagine a world where innovation isn't confined to a conference room or even a Zoom meeting, but it's at the heart of every community and TAP Network envisions and strives to create that every day. So we're all about using new digital tools to tackle big social problems. And what we're seeing in this fast pace and ever-changing world is that many government agencies and nonprofits are struggling to keep up. And it's that they don't have the right digital infrastructure. And sometimes their efforts fall short. So TAP's purpose is really to bridge this digital gap or passion about sharing our digital expertise with you. And by doing so, we're not only just enhancing your capacity for change, but we're also ensuring that the change is deep and far-reaching and resonates with your community and shares your mission. So how do we do this here? We developed high-impact digital platforms like cutting-edge websites, intuitive software apps and data-driven campaigns. Every solution we provide is designed to make a positive impact and most importantly bring about real change. And what sets us apart is that we have global impact, but we have a local heart. So our reach is global, but our approach is very local. And we empower our partners through education. That's what we hope to do here today. And we believe that tools work best when you know how to use it. So we wanna make sure everyone we work with, everyone here today knows how to learn and get the most out of technology and the tools we provide. But lastly, we wanna stay at the digital forefront of technology. Again, this world is ever-changing. So with a backing of AI and user-focused design, we ensure that our partners are ahead of the game. This conversation today is all about technology and how we can use that to make a difference. It was so wonderful to see where you all are calling from, your organizations and how many that you're reaching. And so we want to bring you this innovative solution that we're talking about today. Some people say that what we're talking about is more life-changing and will create a greater impact on society than the creation of electricity or the invention of the internet. But right now, it's transforming how we communicate. Let's move on that. Let's clarify, let's lay the foundation and clarify a couple of things about AI. You may have heard generative AI and you may have heard about chat GPT. We'll get a polling question in a little bit. But picture this, you're shopping online and a little chat bot comes up in the corner to assist you. It's helpful, but it's limited. Now imagine this version of the chat bot was super charged and it was ready for your complex questions and tasks. So that is chat GPT. It's not just a little chat bot. It's like a digital Swiss army knife and whether or not it's helping you draft grant proposals or shape fundraising pitches or create engaging beautiful marketing materials. Chat GPT or as I sometimes call it GPT because it's a mouthful is your digital assistant and it's available 24 seven around the clock. As I mentioned, generative AI, which you've probably seen in the news and chat GPT, the terms might sound interchangeable, but they really aren't. Generative AI is a broader concept. It's about creating new content, whether it's text, images, video, or even music. It's like giving the computer the power to create based on patterns. But on the other hand, chat GPT is a specialized use of this technology. So it's crafted for conversations and it allows for human-like dialogue back and forth.  So in simpler terms, chat GPT is generative AI, but not all generative AI is chat GPT. So hopefully that gives you a little bit of background and lays the foundation.  We're gonna play around with chat GPT and other AI tools, and then we're gonna get your Q&A. But right now I'm gonna kick off a poll, if I can. And I just wanna hear from you guys. How many times in this past month have you used chat GPT? All right, so this is the first time you're hearing about it, once or twice, handful of times where buddies or it's practically my sidekick. I'm gonna let that go for a little bit and I'm gonna share those results with everybody. It looks like we're, there we go. So it's about 14% first time, 42%. The majority of us have heard about it once or twice and we're just getting acquainted. So we're very happy that you're here and hopefully everybody gains something from this talk. 27% a handful of times and 18%. I can't count practically my sidekick. Well, wonderful. Thank you for that. All right, so let's talk a little bit of numbers here. So platforms like Facebook took an entire year to gain a million users. Chat GPT didn't take a year, didn't take a month or even a week. It captivated a million users in just five days. By August 2023, now it has an astonishing 1.4 billion visits. Moving on to its global imprint, I know we have people calling from all over the globe today. The US does lead the charge of users with 15%, but nations like India, Japan and Canada really aren't far behind. And as far as who's using Chat GPT, it's really all-encompassing. So the younger demographic, as you could imagine, 18 to 29 make up 40% of the users. However, it is heartening to see that even the 65-plus demographic is on there at 5%, really showing that it has wide appeal. About 32% of these users have a college degree or higher. And while they're using Chat GPT, many use it for entertainment, about 20%, about 19% use it for education, and about 16% use it to help them professionally, which is why we're all here. But looking beyond the numbers and statistics, while numbers give us scale, and the true measure of its impact is in the transformation and the potential transformation. And this is why I believe some compare it AI to electricity. But consider this example. About 54% of the US adults have a literacy level that's below a sixth grader. And in low-income areas, a staggering 70% of 10-year-olds grapple with understanding basic reading material. They aren't just numbers, they're really indicative of a societal challenge that demands our immediate attention. Some of you on this call may be dealing with health literacy, digital literacy, environmental literacy. And this is where AI, particularly tools like Chat GPT, can really revolutionize how we approach these challenges. So imagine an AI tool that can adapt to an individual's learning rate, their cadence, it could cater to their unique needs and provide real-time assistance. Think of that person, maybe you know someone in your life who finds it difficult to comprehend medical, read a medical prescription or a bank statement or even a public service announcement. So AI has the potential to break down these barriers and simplify complex information to make it easily understandable. So that hopefully paints a big picture, lays the foundation. But you may be asking, why is Chat GPT important to nonprofits? It really enhances engagement.  And it has helped us increase engagement because we can provide those instant responses. We've been able to utilize it to automate routine tasks and this allows your staff and our staff to focus on our organization's main objectives. We were talking about literacy, but in education. So you can use it as an informative resource to broaden the understanding of your or your staffs or even your constituents or communities cause. And you can get valuable insights. It can work data, it can analyze data and all this without straining your budget. The other thing is that it can embrace diverse audiences. So Chat GPT's multi-language capacity and accessibility options really ensures that no one is left out. Okay, we've talked a lot about Chat GPT and AI. Let's get down to how we use it. But first things first, we have to understand what we're dealing with. So here's the deal, Chat GPT is very smart. It's think of it as a robot that writes stuff for us. It takes little pieces of text called tokens and uses them to come up with responses. We can teach it what to say by giving examples, but we have to be very careful about how we do it because it learns from everything it sees. So when we ask Chat GPT for help, we do it using something called a prompt. A prompt is basically we're giving directions. So if we say, tell me how recycling helps the planet, it'll whip up a very nice explanation for us. But here's a tip, think about your audience. Think about who you're talking to and what you wanna say, your audience and your goals. When you're prompting, you wanna keep it clear. And remember, you're in charge of the voice and the tone. So do you wanna make it professional, chill, serious? You can control the vibe by prompt and Tarak is gonna get even more into this. The other cool thing when it comes to utilizing Chat GPT for your grant writing, marketing is that it knows all of the copywriting strategies. There are a lot out there and if you don't remember it or never learned it, don't worry. You just have to prompt it correctly. So what's the takeaway? Learning these basics of prompting the terminology is essentially like getting the keys to the AI kingdom. It's really been a game changer for our work and it's helped us reach more people. It's helped us and our partners reach more people and make a difference, which is why we're all here. Quickly, we'd be remiss to not give you the full picture. So Chat GPT isn't the only game in town. There's some heavy hitters here and they are all doing very cool things on their own. So just quickly, Google's version is called Bard. And you can think of that as like the brainy one and it soaks up everything on the internet. We have Microsoft, they have Bing. That's another smarty pants, but it uses Chat GPT-4 as its brain. It's called Open AI because anyone can utilize this platform. So then we have Claude. Claude is one that is all about getting the conversation right. Similar, Jasper is more of a marketing AI tool. It helps us focus on keywords when we're writing and also SEO. And last but not least, Amazon is in the game as well. They have two different AI prompts, one for logic and one for developers. But among all these, we feel that Chat GPT, it's still our personal favorite and here's why. So it talks how we talk and I can have a conversation with it back and forth. It has a huge knowledge base and the other great thing is that it remembers our Chat. So not only does it get smarter as I continue to chat with it, but I can also refer back to it and send what's called a thread to others. It gives really tailored answers and it can be adjusted for specific jobs. Say you want it to act as a marketer. Say you want it to act as an executive director. Say you want it to act as a copywriter. It can write and give answers based on the role that you give it. And you can have safer conversations. So I've included a link in this slide that just updates all of Chat GPT's policies on how to keep data safe and how they are reducing their harmful replies. And just to round out our Chat GPT crash course as I'd like to call it as what's happening next. So Chat GPT is always getting better. They've released multiple versions and their goal is to make it easier for everyone to use and speak an even more language. That way more people can use it worldwide. There's a lot of competition out there but they're growing in the right direction. Just important to mention the ethical side. So with all this advance in tech, it's super important to use it responsibly. Chat GPT will make sure to avoid harmful content and keep conversations private. You just have to realize that this is still an evolving technology and it does take a human to review. And sometimes it comes up with prompts that may not be factual. So you always have to have that human eye and so as we journey through the dynamic world of Chat GPT and generative AI, I hope you can see that the potential for change is really endless. And I've said a lot of words. I've showed you a lot of numbers in the quick 10, 15 minutes here but it can only go so far. So before we get to your questions, I'm gonna turn this over to Tarik. He's been working hands-on with Chat GPT for over a year and he's gonna provide you with the real world examples and an immersive show and tell. So Tarik, I'm gonna stop sharing my screen and we will get to your questions as well. Cool. So I started sharing my screen. Let me know if you see my screen. It has a joke in it. Yes, we can see it. You see my screen and it has a joke. It's saying non-profits have board members. Chat GPT has circuit boards. Together they're speaking change. Hey, beautiful people, this is Tarik again and I hope you're having an amazing day. So today we're gonna talk about the Chat GPT, not the scary thing. The tool that can change the world, that can do the 10X productivity stuff, blah, blah, blah. So if you are worried about the AI stuff or thinking about like AI is a very scary thing, I'm gonna show you how we can use that tool and how this can be very impactful on our day-to-day basis. I saw the survey result for Lisa asking. It's really good to see that a lot of people are using that on their day-to-day basis. And those who are not familiar with this Chat GPT, don't worry because I'm gonna talk about Chat GPT in depth from scratch to what I can say, like to advanced level. So I'm drinking some water because I have to talk a lot of things today. So be prepared and you need to focus only 20 minutes because that 20 minute will be everything you need to know about Chat GPT. Okay, so let's get started. So when you go to Chat GPT and if you are not familiar with Chat GPT, let me show you the dashboard of Chat GPT first then I come back to the slide. So there's my Chat GPT account. What you can see here, if you go to chat.openai.com, you can create an account. It's very, very, very simple. Simple than creating a Gmail account, a Google account. So I go to chat GPT, chat.openai.com and you can see a lot of things on the left hand side on the bottom top. You don't have to say anything. You see there's a box on bottom saying send a message. That's the part we have to be like where we are gonna send commands. We can say, we called it as a prompt. Prompt mean text format, a text command that we are gonna start chatting with the robot that calls GPT or Chat GPT and they're gonna reply us the message. On the left hand side, you can see a lot of thread out there. You can go there and ask question and we'll have your question there. Sorry. So you can find your question there. So I just want to make everything simple. The send message part is why you are gonna ask the question and that's called the prompt. So let's go to the prompt, how to ask better question. The better question you ask, the better result you will get. So this is very, very important. Using a Chat GPT, just asking question, that's not how you should use that. You have to use Chat GPT in a proper way. So let me give you some idea like how we can use Chat GPT to get most out of it. So how Chat GPT works or the prompt works. The prompt is everything. Is a prompt has two things in general. One is task and context. So task is you are telling this robot or AI tool to do a particular task. Let's say writing an email copy or website copy or Facebook post, whatever it is. And then you have to give them a context for what? For why? So task is very easy to provide but providing context is very, very important because if you don't provide the correct information, it's not gonna provide you the correct answer. So that's why I'm gonna talk about how we can provide better context. So if you see my screen, there was couple of things going on is getting the most from Chat GPT for grant writing. So this is a structure that you can create is like organization overview. You can take a screenshot or you will get the slide end of this webinar. So what you have to do, you have to go there and just create some section for like let's say organization overview. Write two or three sentence about your organization, your program and initiatives, challenge and needs, partnership and collaboration, social media and online presence. Something you can exclude or skip. Last thing is additional context is like something you can say, testimonial is very, very important. Now what happens once we have all the information there, you can go to Chat GPT and when you are asking a question, you can, along with your task, you can provide this context.  When you're asking a particular, when you're giving a particular prompt, you are not actually giving them the right context because they don't know about your organization in depth. But by sending them with this kind of context structure, it becomes very easier to understand Chat GPT who you are. I mean, who your organization is, what it does and how, what kind of problem it solve. Then it becomes very easy to give you an answer. So let me give you an example. Okay, before I give you an example, along with tasks and context, another thing you can provide is some extra example role, preference and tone. Extra is like something you can say, let's say you are asking a particular thing and you are providing a context, but it's not providing the correct result. Then you can give an example like, you can copy a, let's say you want to do a fundraising campaign and it's not creating the correct campaign. You can, from the internet, you can find a really good fundraising campaign and paste it on Chat GPT, telling them this is the format I need and follow this format and create a fundraising campaign for me. So that means that's the example, I will say. So then Chat GPT will know about more, what kind of information you are looking for, then it can provide you the better answer. So let me go to the next slide. I have to go fast because I have to cover a lot of things today. But in case if you have any question, if I miss anything, please go to the Q&A section and ask question. I'll do my best to answer all of your question. So let me go to the next slide. So here's an example. This is a really basic example, but I want to show you the prompt can be really big. It's not just one line prompt. You can do prompt, really long prompt, really big prompt. So here you can see, I was asking for a grand proposal and I put, provide an amount and this is a fake nonprofit that we have created persona and we are using this for an example. So what we are doing here is we're asking a proposal, like run proposal for our urban greening network, UGN and the amount is 250K and then we are providing information like how you have to do, how this happens. This is not 100% like correct or something like that, but I want to show you how we can, by providing better context, the result can be better. You can get most out of it by providing the context. So let me go to the next slide, but before I go to the next slide, let me tell you one thing, you're asking or you may have the question, like show me an example of the, sorry, let me go to, show me an example of the structure, context structure that I have created. So here's an example for our UGN network. So this is the structure I have created, programs and initiative. So this is something I have written, success stories, blah, blah, blah. Everything was written here. What I do normally, either I go to change it and ask about like providing information about my organization or you can go to custom instruction and you can just click on okay and you can just paste about your organization. So what happens is that whenever you are asking a new question, it's actually you fetching your custom instruction, custom data you already provided. So think about like it's kind of sticky notes, like stick above your threads. Whenever you're starting a new thread, a new conversation, it's actually getting the custom instruction information. It means it know about you. Now it can write better information. So you don't have to copy paste the information again and again. So I think it's really good tips and I would recommend to use that. So you will see the difference between the results you get without using custom instruction or without providing a context or with providing context. Okay. So let me go to some example. So, here's a fundraising prompt. I'm sorry. So here's a fundraising prompt that you can see. There's a couple of prompts we have on the ebook. Sorry. So I'm a little bit sick. So I'm having some issue, but that's fine. So here's a couple of prompts. These are the prompts you'll find on the ebook that we are gonna give you for free. So you don't have to worry. What do you have to do? You have to copy this prompt from the ebook and go to your charity account and paste it with your information. Just paste with your information and then see the result that it generate, what create. This is really amazing. So I've been using charity for almost a year, maybe a couple of very good amount of money and I have written to ebook for you guys. And this is 200, 300 hours of work to find some very good prompt. So you just have to copy that and replace the placeholder like your nonprofit name, replace the program or project. Like if we create the context structure, you can just copy the information and paste it here and then go copy that and go to the charity and paste it on charity and see the result that generate. Let me show you another example. This is for the fundraising. So this whole part is a prompt, actually. This is actually a complete prompt. This is not separate from only one prompt. Let me go to the next one is email marketing. That gives you another idea why we should use context. So the first one, if you see the first part, there's a two part of a single prompt. The first part I'm asking, write an email marketing campaign for a nonprofit name to raise awareness of particular problem. So these are the, if you see the third bracket or second bracket, these are the placeholder you have to replace with your information. So you are replacing with the information. If you just copy the first one and go to change it and paste it and want to see the result, you will get a really good result. But if you want to get much better result, then you have to provide some information like provide a brief, but comprehensive overview of your mission, objective and key initiatives of the nonprofit organization you're working on. So this is very, very important. But there's something I call context. So the problem with this tangibility is tangibility has really big database, but it's not really specific or it's not really know about you really in depth. So you have to provide that information so that it can provide you the really good results. So here's an example on the right-hand side, you can see. Let me show you on chat GPT account as well to give you a better idea. So let me go to the first one, let me see. Yeah, that's the fundraising one, you can see. I asked that question and generate the result. Let me go to the next one. As the second one, we are asking for the fundraising campaign. Here's the third one, I can see. We're asking couple of questions actually for the copywriting. So you don't have to worry about, I see a lot of people asking for the prompt but I can find the prompt. You don't have to worry about because I'm gonna give you a complete prompt pack that include has more than 20 plus prompt for absolutely free as a bonus for all the attendees in the window. So I can see we have, as act as a professional human copywriting expert. So we are giving them a role, giving to a role that you have to follow. And then we asking to write a sales copy to attract, to get more donation. Then the whole prompt here, then we are also giving information about just something I call context. So I am giving context about our organization. What happens then? It generates really good sales copy for our landing page or website. This is really amazing when you are gonna use that. You are gonna love it because you don't have to do everything from scratch. You can just go there and just provide your prompt and it gonna generate the content. The thing is like, you have to review everything properly. So let's see if you don't like it, you want to get better. You can ask like, do better. Then it will generate much better information for you. So it becomes very easier for you like this. It generated, let's say, it generate this particular content. Now you don't like it. You always ask Tegibiti on the chat box, hey, make it better. Or let's say something, you want to add something extra here or something it did not do quite right. Then you can ask like, on amplify our mission part, let's say number three part, you can ask Tegibiti, can you rewrite that amplifier mission or add something to that part? Then what happens? It gonna generate the new content with the information you're asking. Also a lot of people ask like, how can we save, how can we generate unique content? One of the simple prompt that you can use, there's a lot of tool out there that you can use to actually rewrite that content to make it really unique. But to make it easier for you, one thing you can do after your prompt that you're asking that you're providing to Tegibiti, you can ask, do not copy or plagiarize. Do not copy from external sources or plagiarize. What happens then? Tegibiti will know, it can't actually copy any extra sources. You have to create a unique content. Also it needs to be keeping the content needs to be not plagiarized. So you are giving them instruction. Also you can say, if the tone is not really helpful, you can ask like, can you act like a professional copywriting expert with 20 years experience who has professional, like who is really professional who has like warm tone or whatever tone you want, you can ask that on the prompt. So the much better question you ask the better result you'll get. So I have the e-book for you. Like let me show you the e-book first very quickly. So there's the free version of the e-book that you are going to get that has. So let me do a quick throw out of the e-book. Here you can see. So there's a couple of categories out there like email marketing, run proposal has the prompt. It has also answer example and the prompt as well. You just have to copy that like let's say copy and go to Tegibiti, replace the placeholder and paste it. That's it. You don't have to do anything. In case if you want to change anything or if it's not generating 100% result then use the context method that I have discussed before. So the better question you ask the better result you'll get. So then we have social media marketing and we have some resources for you. Like if you want to generate images, if you want to generate images, if you want to generate any voice, video, anything like this, we have the resources added on the e-book as well. So let me go back at the first part. So that's the e-book you're gonna get. So you don't have to worry about that. Just copy that and paste it. Copy the prompt, paste it. You have everything you needed. So that's pretty much to give you an idea about how to use Tegibiti and how to give a better context, better information and get better results. So let me go to the slide again. There's the slide. There's a couple of alternatives out there. There's not one, two, three. That's a really good amount of competitor of Tegibiti, but none of them can really beat Tegibiti on a high level. There's Google Word, there's a cloud. So I'll recommend you, like, if you want to generate a really good content, let's say for email marketing or social media marketing or social media post newsletter, I would recommend to check out the cloud. Because it can provide more accurate answer and more better results. So I would recommend to copy the prompt, replace the placeholder, and test on the three platforms and see which one performs better in case you want to get good results. Another thing to forget, another thing I forgot to tell you is these prompts are for, like, it's really working for the 3.5. That means GPT 3.5. That means the free version of the Tegibiti. You don't have to use the paid version in order to use the prompt. These are absolutely free to use. So if I show you my account, that's the account I have without pro version. I don't have the plus version, but the free version is enough to get started. I would recommend you to start with Tegibiti slowly, slowly. Then when you're thinking that this is a really game changer tool, then upgrade it to the plus. Now, let me go back to the slide again. So there's a couple of alternatives out there for Google Word and Clothing. Clothing will be the top recommended tool to try out. But if you want to stick to one tool, that will be GPT. None of them can be GPT. So let me go to the next slide. This is the eBook that you're going to get for free, and it has 20 plus prompt, resources, everything you need it. It took a 30 second break. Then I'll come back. So I'm back. So that's the bonus you are going to get. You don't have to worry. A lot of people are typing why I am going to get that eBook. You are going to get that eBook on your email after the webinar ends. So don't worry about that. You're going to get that if you still don't get the free eBook. Please reach out to me. I'll send you the eBook copy personally. And you will have everything you need on the free version of eBook. This, those who are already using GPD and already want to get the expert version, then you can get our pro version that we have. It has 80 plus GPD prompts. It has a mid-journey, Google Word, and it has tons of resource library. It covers 15 plus categories like press release, web copy writing, and tons of categories like email copy. I think it has 30 plus email prompts and I spend around 200 plus hours by writing. That is really cheap. I think it's only cost less than going out for a lunch. So this is recommended for someone who already using that or already using GPD for everyday basis and they want to get the expert version. You can get that. And if you are just starting out I will not recommend you to get that. I would recommend you to use the free version. This is enough for you. And I hope this will be really helpful. If you are using copywriting, grant proposal, email marketing, social media prompt that you needed. And these are all super prompt. Anytime if you are not getting the result again, just to sum up everything, if you are not getting the good result, always use the context please. You have to provide the information. Keep in mind if it's not providing the right answer, that means it's not it is having issue. It's not about you knowing about the task properly. People are asking where to get the paid version. You can go to tapnp.ai that's our website. Tapnp.ai to buy the ebook right away. That's our version 2 going on. I'm working on the version 3.0 and the 3.0 will have tons of more prompt and it also has the GPT-4 prompts and couple of other tool prompt in it. So if you purchase the ebook today, you will also get the updated version for absolutely free when we have that launched. So let me sum up everything. I hope that gives any clear idea how to use LGBT and how to use LGBT better and how to utilize this resources. So I will jump into I think Lisa can you hear me? I think you can too. Would you like to go through some questions? Let's jump into a few questions and then I can get into our marketing and support services. I have a question for you, Tarek because you've used them all. If you could just quickly talk about the pros and cons of using the GPT versus BARD or any of the other ones. I mean from my experience you know we could talk about this internally but BARD has access to real the internet it's up to date. I prefer using a combo but what do you think about using the differences and when you use which? BARD is very good when it comes to web accessibility and up to date feature but one thing to keep in this mind you can't beat the GPT. The GPT is the king of the AI universe. I'm not getting paid from the GPT but I want to let you know that the GPT is the first tool you have to get started then you can look for clothing, entropic, Lamma, or any other tool if you have time but the one and only tool to get started will be the GPT and to answer your question Lisa the GPT for recently announced the web accessibility feature so if you have the upgraded version you can use the web browsing feature so that you can browse the internet and get the relevant information so that will be helpful and in case if you want to use the free version I mean web accessibility thing we'll always use Google word but Google word has really good feature as well they actually work really good when you have like let's say searching on something on Google without searching on Google go to Google word and ask that question it will provide you better response, better result and you talk a little bit but the free versus the paid version from my understanding and experience the paid version tends to give a lot less for for chat GPT when you upgrade you pay the 12 I think it's 12.99 a month but I find that it provides a lot more accurate of information less accurate information are there any other differences between the paid version of chat GPT and free that you want to mention okay can you repeat the question again are there any other differences besides accuracy of information between chat GPT the free version and the paid version yes chat GPT 3.5 and 4 are two different model so this is actually they have 3.5 and 4 model so of course the paid version will be better than free version but if you want to get started you can always use the free version you don't have to upgrade right now only upgrade when you think it's time to upgrade along that you don't have to upgrade that you can use the free version this is enough for a lot of people to get started but if you upgrade on paid plan I mean 20 bucks plan this will be the best investment so far because I personally say this is if you want to spend on an employee then spend on chat GPT pro plan because you can have a 20 bucks employee per month who can do 7 works every day for you everywhere awesome a couple more questions we have a lot of great questions one was about when you can assign roles you and I were both talking about prompting chat GPT and having it be a creative director a copywriter and someone says how can you assign roles such as you're a rabbi or the victim of sexual abuse and this is very helpful when putting your audience in there when putting characteristics demographics things that you know about the audience and then you can rely on chat GPT to fill in that information to write something from the perspective of that audience so it's a balance between you providing the information that you know as well as the information that it gives back and we do this a lot especially working with various audiences so that was there's another yeah go ahead I was answering some questions people are asking the URL of the pro version of my ebook is tap t-a-p-p-n-p dot a-i t-a-p-p-n-p dot at least you can pronounce that better so whoever asking you can get it on the free version you are going to get that on your email after this webinar if you don't get that please reach out to me personally I'll send you the copy for absolutely free there was another question about copyright and IP in proposal language and for the most part once you produce content using chat GPT you own the rights but that is not a blanket statement and they are always updating the rules and regulations and we can put the link to chat GPT legal page and legal ease on there however there are certain instances where we could say it's not a copyright if you're developing a picture an image potentially using the journey or another AI and then you tend to put it on a product and sell it that is typically not allowed however the content that you produce if it was for a grant or social media that is you would hold the rights to that so hopefully that answers there's a couple of questions can I answer a couple of questions was this presentation based on free version of chat GPT yes the free version and the free version of the ebook as well absolutely free use that please use it at least for one time and you are going to love that I tried to play with chat GPT a few months ago I wanted payment free version how do I get it's very easy just go sign up for account create a free account and you will have the free version created you don't have to upgrade that should you update the custom instruction often or set it and forget it it's mostly I have two different gbd account and for my task I'm not using custom instruction often because my task related to dynamic role so I'm not actually asking a lot of questions but whenever I do testing with my prompt for nonprofit I use custom instruction so that it becomes consistent and I don't have to provide I don't have to provide context every time I ask a question why do you find custom instruction let me show you very very simple you go to bottom you go to your account and there's option for custom instruction why you can put your custom instruction raise if you don't see that you can go to settings and on the beta version you can enable that don't worry about that and Lisa you want to go I'm sure there's George is asking a question before Tarek ends can he re-show the screen of what we should include about the project NGO mission before we start can you please project NGO I'm sorry did you see the question of George Cummings on Q&A okay we buy did you say we will get an updated book yes one yes that if you went on there and bought the paid version you will get an updated version when it comes out there we go our emails are on the slides and we can also put them in the chat I'll let there's a question there are some interesting comments and questions in the chat and I agree Tarek and I are trying to go through those now maybe Aretha will let us know at the end if they will be shown in the recording I'm unsure of that so Katie asks how can you get AI to help finding images we may want to complement the text and what about using AI to help and create charts and graphs this is something that we've used internally as an agency and we've seen it grow the capabilities over the past couple months and it's continuing to be enhanced platforms like Canva which also have a free and paid version now have AI integrated so you could type the theme of your text a child reading a mountain side with a woman standing on it and it will generate and find those pictures for you and there are other examples and many platforms that forms that have that capability I think it's one of the things that I find so amazing is that because it is open AI and anyone can access the code to create this a lot of new businesses a lot of entrepreneurs are creating tools that we can use and it really levels the playing field between big corporations with huge marketing budgets and nonprofits okay do you want to share your screen? sure and we have a couple more minutes and I did see some questions about our services and being able to utilize our expertise so I will just explain that and feel free Tarek to look through the questions as I looking through going through this and yes some people are asking I just saw some people chatting about like there was a type on marketing they have very good eye on that thank you so one thing is make difference between AI and human is human made mistakes AI did not so that was by type of I may not by the AI so if you want to have something really unique that can be detected by any AI tool that was written by AI just made some typos then that will never think like this is written by AI because human made mistakes not AI but whenever you get a result generated result using any nlp based tool please double check the information before use that I also send the link of the e-book the paid version we call the experts version on chat so in case if you have an issue you can go there and you will get the free version of the e-book on your email so you don't have to worry about that alright so as TechSoup's exclusive provider for digital services you can go into their website and under website services you'll explore some of the services that we have here is a bigger menu of everything from strategy to inbound marketing to branding that we do as an agency including and everything as we mentioned is not only growth driven but it's also unique to you we understand that each non-profit has a unique set of goals and missions and budget and we make sure that those are services are tailored to you so there is a link to our website as well as our emails not only the general sales email but at the beginning of the powerpoint Tarex email is there as well as mine link in profile so feel free to connect and we'd love to hear from you any other questions Tarex that you've seen that you're interested in yes I'm answering a couple of questions on Q&A so yes there's tons of questions I think I need a really good amount of time to answer everything but yes one other thing I'll recommend everyone please don't overthink this tool this is really really really easy to use please never overthink that you have to write really good prompt how you are going to get that prompt that's why I have the free version of the please use that prompt I'll start using that then you are going to love that most of the people can get started because of their thinking this is really really tough they will need some sort of knowledge technical knowledge to that's why I recommend please just create an account after this webinar and start writing asking any question you have and you are going to love that and if you like this webinar please don't forget to share your knowledge share your feedback on chat that will encourage me to write or create a better product for you guys thank you everyone