Testing/fuzzing an ncurses-like (text) ui

I’m working on a program that uses github.com/rivo/tview to present some configuration options to the user. I have navigated through the ui and things look good right now.

However, I need to automate these tests. The obvious choice here is expect or one of the go packages offering this functionality, for example github.com/google/goexpect. Getting goexpect to work with tview is a battle I’ve yet to win fully; tview’s Application.Run() no longer returns immediately, which is an improvement, but so far I haven’t managed any navigation with the escape sequences I’ve sent.

How would you go about automated testing of an ncurses-like ui? I’d prefer a solution using go, but I am open to non-go solutions as well.

I’m currently using goexpect along with github.com/creack/pty. Some googling led me to github.com/Azure/go-ansiterm and its importers, such as github.com/kriskowal/cops/vtio - but I’m not yet certain whether they’re any help.

Once I’m at a point where the test can be automated, I hope to hook it up to dvyukov’s go-fuzz. I want to use fuzzing to find any input sequences that can cause hangs or crashes. Currently I re-exec os.Args[0] to connect to the pty, though if it’s possible I suspect that avoiding the exec would greatly increase fuzzing speed. Plus I suspect the mechanism used to track fuzz coverage would be broken by exec…

1 Like

I made progress, recording here for posterity.

After looking more I realized that github.com/gdamore/tcell (which tview relies upon) allows you to create a simulated screen that you can send events to, capture state of, etc. And tview allows you to override its default screen. So I create/initialize a simulated screen and set up a tview.Application with it. I use protobuf to decode the fuzzer’s []byte into a struct, which contains initial state for the backend followed by any number of events. These events can be user input or limited state changes for the backend.

So far so good; now I need to flesh out other parts of the code.


Design Draft: First Class Fuzzing