What and when to unit test?

I'm currently making a TUI wrapper for flatpak using Ratatui, and I know it is a good practice to do unit tests on your code, but I genuinely have no idea what to even test. Like almost everything I know that could bug I already test manually when developing and, considering it is a TUI wrapper, I don't think there's that much room for tests compared to libraries and such.
I can only think of testing CLI "calls", but it would be very restricted and couldn't be replicated in GitHub actions I guess.
Could someone help me understand how to test my code? Thanks a lot.

When you develop TUI (or GUI) you usually have so-called presentation logic: If user clicked on FOO and input field BAR is not empty, the form should show BUZ. As any logic, it might also have bugs.

The best practice here is to extract as much logic as possible from UI code (to make UI layer at thin, as possible) and cover logic with tests.

Classic patterns here:

  • MVC
  • MVP
  • MVVM

With each of them you can extract logic to controller/presenter/model, and cover with tests.

The next question is "what to test". Begin with typical user scenarios (aka sunny day scenarios): which problems usually users solve with your app, and be sure these scenarios are tested.

Then, move to rainy day (when something goes wrong, and you need to process an error)

Testing is an extremely wide subject, even if you restrict it to unit tests! To expand a bit on throwable-one's reply for tests more generally:

One useful rule-of-thumb is that tests are most valuable when they verify that your changes have not broken anything; if you have a good idea of where anything might need changes then that's a place to start by writing tests for the behavior you don't want to change when you're updating the implementation.

Another good trick is before making a change, write (failing) tests for the behavior you think you'll end up with, then you can quickly iterate making changes and running the tests until they pass (or you figure out that's not the right behavior)

Finally for now, don't overthink tests: despite what many many many books and blog posts will tell you, they're there to help you so only use them as much as you find them helping you. As you get more experience with them, you figure out more ways they can help, but don't fall into the trap of feeling bad for not having met some arbitrary bar you don't even really understand (after all, many of these writers don't really understand their own advice!)

What do you, as a human, do when you run your TUI to check whether you didn't break it? To start out, just try to move that to cargo test so you don't need to do it manually.

That will mean you probably need various refactors to make testing feasible -- use write! instead of println! for example -- but that's fine. It's worth it.

To quote Test smarter, not harder - lukeplant.me.uk,

Your overall testing strategy should feel like “I get that computer to do so much work for me!”, not ”My RSI and bleeding fingers have hopefully appeased the testing gods and atoned for my previous omissions”.

I'm a novice working on a ratatui based app as well; just sharing what has worked for me. Building on throwable-one' s anwer:
I specifically have two crates, the outer crate serves the TUI, where as the inner crate is a library which provided all the 'functional logic'. For example, my TUI accepts user agrs such as grep pattern path. My functional logic spawns a process with these args, reads outputs, does some transformation. Since this is a lib of its own, it's really easy to do standard unit testing. My outer tui crate just uses the API I expose and does all the 'presentation logic'.
This may not be the best way to go about this but def is solution that works.