Testing iOS Backend?

Hi there,

Relatively new to iOS programming, but been programming other stuff for awhile. I'm writing an app with a MVVC architecture (s/o CS193p lmao), and I have a Model (really a couple of Models) with some functionality that involves requesting data from the Internet, and parsing it. As you might expect, I have a Model that performs the web scraping, and one that handles the parsing for a specific data format, so it can be presented eventually. I don't currently have a "frontend", since I wanted to flesh out more of the backend first.

Which brings me to my question - what's the best way to sanity check this is all working, that is, how can I run this backend code and just verify things are behaving? Because this involves a couple different models interacting, I'm relying on XCode to resolve what each type is and where I've defined it, so I couldn't really just compile my code from the command line without getting a bunch of missing definition/import errors. However, I'm not sure how to actually "run" anything in XCode without a frontend, it also seems kind of silly to just render a simple View that calls my code in an `.onAppear` or something. If I was using another language, I might be asking for the equivalent of a "main" function I could stick in some of my Swift files to instantiate some of my structs and call some functions, but from what I understand about iOS the point of entry for an app is more complicated to that.

So what's the best practice here? Is it Playgrounds, or XCode Tests or something? What do people like to use?

11 comments · 80% upvoted · other discussions

comments

noidtiz

The last time i did this earlier this year i used the XCode console. i had to extract some nested data to JSON format and wanted to make sure it was doing it correctly.

I can’t remember the exact library/methods i used but i think JSONDecoder() would be a decent bet for just printing to the console. Otherwise the only other thing i’d suggest is rough-and-ready SwiftUI views which shouldn’t take long to do.

doodlebug80085 [OP]

I see what you mean! I don't really have a problem printing my program's data to the console, my issue is actually calling and executing my code without using a View in the Preview tab. Since I haven't made my frontend yet, I could just make a Text View with an .onAppear modifier to call my code from the Simulator/Preview tab, but that seems silly. I wasn't sure if XCode had an alternative means of running backend code.

noidtiz

Ok yeah, my mistake, i misunderstood and oversimplified your post. it’s late where i am but i should have read it again.

i don’t really have any experience of Vapor but it is a popular package for server-side Swift. on their site (Vapor.codes) they have a ready-made example which is 6 lines code, though it’d be more than that to conform it to your two models. The only way i could see it conflicting with the @main entrypoint wrapper is if XCode starts asking you to explicitly type everything, as Vapor using “Application” is a little ambiguous of an init call. I have no first-hand experience with Vapor so i don’t want to lead you on a wild goose chase here.

doodlebug80085 [OP]

Yah, I've used Vapor before, and I think you're right and that would work. I guess I'm just spoiled from other languages (cough, python) where you can just sort of set up a `main` function from some of your backend code and start running things then and there.

I ended up writing XCode tests to instantiate/experiment with things from my backend, and not do the whole "run a Simulator and make a View and test stuff there" hack, only to learn that XCode tests run a device simulator anyway! I guess that's where the tests get executed.

noidtiz

i know what you mean, the last 3 months i’ve been building in Node JS and Django. i’m a little rusty XCode. Good luck!

-darkabyss-

If you write unit tests, it will be even useful when the app is developed. You'd have to have some sort of networking object that handles API calls (I like having a network manager with a single function that fires the request and an enum that has a function returning a urlrequest object for your endpoints) and create unit test funcs for each endpoints. If you have multiple login API calls, you'll have to nest them and fulfill the XCExpectation at the end of the chain.

doodlebug80085 [OP]

Yah, I ended up just using XCode tests. I had a slight aversion to this, since I’m not technically making testing code right now, more just trying to experiment with my implementation and iterate on its output as I settle on more of a finalized design - in the same way I’ll use intermediate Python scripts to interact with my implementation when writing Python, but will still have a separate Pytest suite for unit testing. I guess I’m just being pedantic about what belongs in a testing suite and what doesn’t LOL

-darkabyss-

Theres always the option of having more than one test targets, or put the networking/persistence stuff in a package and have a macos cli/ios app target to 'test' the things. Workspaces are great for this.

SwiftlyGoingInsane

I mean you could throw together a crappy UI in a few minutes to test it, it doesn’t have to be special, but if you specifically don’t want to do that, I’d say just write some tests

doodlebug80085 [OP]

Yah, to your first point, I was kind of thinking or making just like, ~a~ View to call my code, but I wasn't sure if there was a better alternative than having to run an entire simulator or preview just to run code that doesn't really use it anyway.

XCode Tests seem maybe a little more appropriate, but I'm not really writing tests, more just a middle ground of running code to experiment with output/check things look alright.

EDIT: XCode tests end up running a device simulator anyway, so

swiftfoxsw

XCTest is the answer. Write the tests that validate each method + their error handling, and run them before every release build.

Doing this quick practice will save you way more time & trouble than it costs. If you leave the project and come back in a few months or a year you likely won’t remember small details that needed to be validated, your tests are your sanity check that everything acts how you left it…and that if you make future changes they don’t break what you’ve already built.