Hi. We’re back with looking at using Claude for different things within our iOS project. And one of the things I wanted to do was see, can I get Claude to write some tests? There are several ways you can do this. You can imagine the test can be really useful in AI generated code. Either you can write the tests or you can really carefully code review the tests. You can make sure that right tests are there, and then you can be much more confident that any code that this generating is behaving the way that you wish it to.
In this instance, I’m kind of slightly back to front. I’ve got it to generate some code. Now, I want it to generate some tests, make sure that those tests pass, and I’m happy with what those tests are doing. I don’t think any of them made previous videos, but in several of the other lessons in this course, I attempted to make some tests using AI, and it almost always failed miserably. And I spent many, many, many minutes, hours trying to get AI to debug them. I’ve had better experience with Claude, so we’ll see how well we do here today.
We’re going to start off with a very simple use case. And that is the time service over at the time service here. It is really quite simple. There is nothing complicated in terms of threading. There’s no mocking of APIs that we need to do. I’m still in the same session that I was in before, and I’m going to ask Claude, please, could you help me write some tests for the time service?
Okay, let’s see how well this is. Okay, so it’s going to it doesn’t understand anything about how our tests work at the moment. So it’s going to have a look at those. It’s then going to write some tests. And it’s determined three things that it wants to do within there. It’s quite nice that it writes these plans for us. And then we can very clearly see it go through them.
So also worth saying that although Claude is a command line utility, if you don’t like command line utilities, it will integrate with various IDEs including JetBrains, IntelliJ, and Visual Studio Code. I’m not intending to show that here, but if you can read the docs, you can find out how to do these things.
Okay, so it says that it has added comprehensive tests for the time service in yesterday’s weather tests. So it’s not created a new file, but it’s put them in our existing test file. And those tests do these things. Interestingly, it uses the Swift testing framework. This was I mentioned before that I was trying to get other things to write tests. Getting it to use Swift testing was really hard work. It really, really wanted to use XCTest. And then it would have a go and a swift testing decided didn’t work and then go back to XCTest. So it’s interesting to me that it started with swift testing because that’s what I want it to do.
Okay, so let’s take a look in Xcode. We’ll notice that we’ve got a modification here. And we have it’s made some tests. We’ve got something where we’re passing in a date that we’ve artificially constructed and then checking that the format that comes out is exactly, is contains what we’d expect it to. Same again getting the hour from the date. And then just checking some other things as well that yesterday it kind of time is before now. Test it the format with different time zones works as well. So they’re fairly reasonable tests. I’m going to try running them. I want to see what happens.
So it succeeded building. And then it goes off and creates some iPhone clones. Installs the app. Runs it. I’m going to allow it to use the location. Okay, four of my tests worked. One of them didn’t. Right, so this is nice. So this expectation failed. That formatted date 15th of June, 2025, 1430 contains 230. Well, I assume this is going to be a problematic test depending on the locale that you’re running it in. Grown ups use 1430 for the time. And I believe Americans use 230. So I’m going to see what Claude says if I’m going to give it this answer.
So, all but one of the tests worked. I’m going to see what it suggests. I have a suspicion that I can make it work for me. I mean, yeah, that’s the solution. I can make it work for me. My guess is if you run this and your simulator is in a US locale, then it’ll go back to being 230. I wonder whether I can ask it that. Will this work if the simulator is in the US locale as well? Formatter uses. Oh, okay. I don’t hate that. So what it’s now suggesting is but it’s either 1430 or 230. I don’t hate that. Okay, we’ll go with that.
And now if I go in here and run these tests, then I imagine they’ll pass. Now, all the tests passed. Now, I don’t know why. Why am I typing that? I’m literally now going to pay money for it to process something that is meaningless to it. It just feels polite, doesn’t it? Please, could you give me strategy for testing the rest of the app? This is living slightly dangerously. Because those tests were fairly easy. Let’s see if it can cope with more complex ones.
It thinks high. High priority is the weather API client. Because that’s high. Very. It wants a mock URL session. I mean, yes, but good luck. That’s the thing that the other AIs really screwed up. The weather ViewModel business logic that seems makes some like some sense. It needs to mock CL location manager. All right, I’m going to live dangerously. So, please, can you firstly commit what you’ve done so far and then try and implement all these tests?
Okay, I’m going to let it come in, do as many git commits as it wants in this session. Yes, you can commit that. That’s fine. Now, there are ways that you can run Claude what you might call YOLO mode, where essentially it’ll just you give it permission to do whatever it wants within reason. Oh, not even within reason, it could, in theory, do whatever it wants, increment any, could do any web stuff. It can do any bash stuff. It can do what it wants. I haven’t configured that here, but you could do that once you’re comfortable with it.
You can also get it to work with MCPs, that’s out of the scope of this. But we will look at writing more about that or presenting more videos about that in a future course. But that gives Claude the ability to interact with other things as well in agent mode. In addition to just bash in the search, like.
Okay, we’ve got an error, which is a bit strange. How is it doing with that? I’ll cut the video here. Otherwise you’ll get really bored watching it. We’ll come back when it’s finished faffing. Okay, so it now has completed all of these things. We scroll up a little bit. It’s got a test suite. Summary. It’s got the time service that we saw before with five tests. Seven tests in the weather API, two in the weather view model, three in the location manager, six in the weather assets and three in the UI. I will be surprised if they run. Never mind, they pass. Let’s have a look at what some of these are.
So first of all, let’s put them all in one file I think, which is not my favorite thing in the world, but I might ask it to split them out. But we’ve got the time service tests here, so we’ve already handled then let’s take a look. We’ve got the this is the weather API clone. So it’s created this mock network session, which is a network session here. It’s created a new protocol called Network Session, which is very interesting. Every other time I’ve built these tests, the first time this is the end result. It needs to create a network session protocol, but it doesn’t realize that at first, and we end up with it being told you can’t override something in the URL session. And then this is the solution it comes up with. So it’s really interesting that that has come up and been implemented right away. Quite impressed with that.
Go back to my tests. And then within there we’re going to test successful weather fetch. So let’s hear it mocks the results that it thinks that this is what the API would return. It’s going to go off and it mocks that response, then requests it and then it gets it manages to pull out the information from there. So that’s reasonable test. Then we go through and we look at network errors, invalid HTTP responses, and invalid JSON responses. So a whole host of different things that we’d probably write.
I would quite like to go through and check that these work, but we’re not going to do that now. In fact, all I’m going to do is try and run the entire test suite and we’ll see how far we get. Here we go. It built, which again, I say is more impressive than you might realize. And there’s a whole host of errors, but quite a lot have passed. It needs me to click a button, which I’m sure you can automate, but I know not how you know. Allow you again.
Okay, let’s take a look at this one here. Test precipitation form. So there’s a result here. Oh, this is a rounding thing. Look, the weather asset’s precipitation from 10.25 should go to 10.2. And it’s gone 10.2, 10.3. So this is where, if we had slightly better integration, I’d like to think that it could magically link these things together. But instead I’m going to copy this and go to here and put some of these tests failed. It reckons it can. I did not know this. It’s going to try and build it and run it itself. I don’t think it will. Oh I see, okay. I don’t believe for a second this will work. So attempt at that and then realize it doesn’t have the right simulator. I don’t think so. That’s going to try again. Let’s give that a go.
Okay, so I couldn’t. Despite its best efforts, it wasn’t able to run those tests, which is a bit disappointing. So what I’m going to do is pass in some of the error message that it has had got. So I’ve got this one here. Let’s now change 10.3. So much here. I’m not sure that’s necessarily the right answer, but never mind. Call error here. This is where, on line 130. So it thinks that’s going to fix the failing test. Let’s see where we are with these tests. This one here should now be fixed. I’m not particularly happy with the fix, but this should be fixed.
They are now all green, and then we’re here. And we may have fixed one of these. One, two, three, four, five. Now we still have five errors. So this is line 139. Not sure that this is going to make any difference, but let’s try that one again. So if we’d been able to get xcodebuild to work, which maybe you can, then this loop could be entirely within Claude without us doing anything. Yeah. Oh, finally, we fix that test. Okay, let’s put over the top. Now, I assume that the other four tests still don’t work. No, they don’t. So this is line 197. 09197. Paste that in. That’s apparently fixed. It is. Wow. Okay. And then we have the same error for on lines two, nine, seven, and 264. Same error. Lines 297 and 264. Okay. And those two fixed. Yes, we have one more to fix. And with that, for the UI tests. And that is on line 350. Was this error. 350 is this error. So you can imagine that with a GUI this would be considerably easier. Or if I’d managed to get it to integrate correctly with Xcode build.
Okay, let’s try that one again. All right. And then if I go to that line three means that all of yesterday’s weather tests here, let’s run this. Do they all pass now? Yes they do! Okay. So we now have one test that’s a problem. So this is inside UI tests. Line 40 inside UI tests line 40. Okay. So it disappears too quickly. I’m going to allow while using app. That time it passed. I think that means that I can run the entire test suite again, and it’ll work. I might need to be here to click some buttons because I haven’t worked out how to fix that. Not that one. That one’s good. That one allow while using. That one won’t need it again.
Okay, so we have exactly the same error that we had before, which may or may not occur, depending on how fast it loads. I think. So in that instance that then passed. So it’s a it’s a stupid timing issue. So I’m okay with that. So it’s built a test suite which the bits that we’ve looked at seem pretty reasonable. And it now passes and we fixed it. It was a kind of tedious manual thing, but I didn’t have to pay much attention to it.
I would suggest that you absolutely would want to go through and make sure that these tests make sense, and they do what you expect them to do. And that way you’ve got a backup for understanding what the code does. A final thing then I want to do is, please commit all of this because the tests now pass. So that’s written me the commit message. And that’s that. Done. And then I’m just going to say, how much did that cost me? In total, I spent $2.63 writing a test suite that albeit unchecked at the moment would have taken me an incredibly long time to write myself.
So with that, we have managed to create an app that uses CoreLocation. It uses an external API to request the weather from where I am at this point yesterday. I mean, this isn’t a particularly attractive display, but it is displaying it. It uses modern concurrency. It uses viewmodels. It uses Swift UI. It is a starting place. And I think it’s not that unreasonable. It is not App Store ready. It needs a lot of care and attention to be able to get to that stage. But this is demonstrated what you can do using some of these tools.
Thank you. Bye.