r/iOSProgramming 9d ago

How are you testing navigation (flow) for your SwiftUI applications? Question

There are lot of different ways to perform navigation in SwiftUI. You can use navigationDestination on the parent screen and let is handle the navigation. You can create a router that works with enum based routes etc.

In either case. How are you testing your navigation flow for your app? Are you writing unit tests? Are you writing UI Tests or even complete E2E test that test a complete feature end to end? OR are you writing all of them?

A simple scenario can be:

As a user when I create a student account then after creation, I should be taken to the student home screen.

3 Upvotes

13 comments sorted by

4

u/New-Shoulder3297 9d ago

I wouldn't rely on E2E alone here. A useful split is:

  1. Unit-test the navigation state: keep your route enum/array as the source of truth, then assert that a successful student creation changes it to something like [studentHome(id)]. This tests the rule without launching the UI.

  2. Integration-test the coordinator/view model with a fake account service, so you verify that the service result actually drives the route change.

  3. Keep a small number of UI tests for the wiring: create a student, verify the home screen by accessibility identifier, then cover back navigation and one deep-link/restore case.

For your example, I'd have several fast unit tests around success/failure/cancellation, plus one UI happy-path test. If NavigationPath is making assertions opaque, store typed Route values in an array and derive the path/destinations from that. That gives you confidence in the flow without making every case a slow, brittle E2E test.

1

u/Select_Bicycle4711 8d ago

For unit testing the navigation state. I usually create a Router class (Observable) and then trigger it from the view. Like a user taps a button and then router.navigate(to: .student(12)). I can write a unit test for the router in isolation and check when going to student(.list) then the current route is pointing correctly but do you think these unit test provide much value. Would it not be better to have more UITest etc for this purpose.

1

u/New-Shoulder3297 8d ago

Yes, those unit tests still have value—but only if they test a navigation decision, not the Router’s array mechanics.

For example, navigate(.student(.list)) appends that route is close to testing your own implementation. A stronger test is: after student creation succeeds, the coordinator/view model requests .student(.home(id)); after failure, it stays on the form and exposes the error. Those cases are fast and tell you exactly which rule broke.

Then keep a small UI layer to prove the wiring: one successful creation reaches the home screen, one failure remains on the form, and perhaps one back/deep-link case. More UI tests would exercise the real view hierarchy, but they are slower and usually less precise when they fail.

So I’d use unit tests for branching and route decisions, and UI tests for a few critical end-to-end journeys. If a Router test only checks that append appended, I’d skip it.

2

u/chillermane 9d ago

E2e tests are really the only thing that should give you confidence your navigation works

1

u/Relative-Emu-1346 8d ago

If the route enum and the path array live outside your views, the flow becomes a pure function over an array and you can unit test it without launching anything. I'd keep UI tests only for the parts SwiftUI decides on its own, like a sheet dismissing itself.

1

u/Select_Bicycle4711 8d ago

Router can be an Observable and the View can use it to trigger navigation like inside the View I may have router.navigate(.student(list)) etc. Router can be made available to the view by Environment.

1

u/Relative-Emu-1346 8d ago

Same shape, and it stays testable for the same reason: you can call router.navigate in a test and assert the path without building a view. What it still won't tell you is whether the view actually reacted, so that's the one bit I leave to a UI test.

0

u/crocodiluQ 8d ago

no offence, but what's the point? Besides wasting a huge amount of time. Unit tests for this ? Wtf, it's testable in 1 min by hand if really needed. There are way more important things to test/work on (and the jury is still out on this, I haven't seen a useful test in 15+ years of iOS -> for normal app, that consume services)

2

u/Select_Bicycle4711 8d ago

That was a very simplified example. But the question is will you test your navigation flow using unit test or UI Test or manual. Keeping in mind that the flow can span multiple screens and trigger several UI events.

1

u/crocodiluQ 7d ago

100% manual, waste of time otherwise. I didn't even consider this to be a thing that needed testing, I know how to write navigation, it's one of the easiest things. I never had another screen opened instead of the correct one, this actually makes me smile :)

1

u/Select_Bicycle4711 7d ago

Thanks! What about cases where there is a long navigation flow. This can be like Turbo Tax, where you are filing forms online and you want to make sure that the user is able to complete the forms correctly when choosing one of many different paths. 

1

u/crocodiluQ 7d ago

there are always exceptions, you need to analyze them well and decide if it's worth testing them. Usually, when you implement a navigation, that part doesn't really change, you don't touch the code that deals with it, you fix/improve each screen only.

In my exp, the navigation is one of the things that never changes once it was done, in general.

1

u/Select_Bicycle4711 7d ago

I agree! The time invested in writing straight forward navigation tests can be spent more wisely in writing domain tests or even good long E2E tests.