RSS 2025-12-06 03:49
libraries

How do you design the table-driven tests in Go?

来源:Reddit r/golang

Some time ago I created a mini game written completely with Go. It was a hobby and a sandbox for learning the language.

Testing in Go is great, but over time I faced an issue. My end‑to‑end (integration) tests grew complex and it became very hard to refactor when I was changing the behaviour of old features. Also, thanks to the AI I made that code base even worse. I tried to be lazy at some moment and I’m sorry for that. It became a disaster so I ended up deleting all end-to-end testing.

So, I started from scratch. I created an internal micro-library that lets me write tests like the following code.

```go var scenarios = []table_core.Scenario{ table_core.MakeIsolatedScenario( []table_core.Step{ assertion.PlayerNotAuthorized(3), util.OnEnd( events.RegisterWithPassword(3), assertion.PlayerAuthorized(3), ), events.UpdatePlayerName(3, "Player-3-vs-Bot"), util.OnEnd( events.StartVsBot(3, "Easy"), assertion.ARoomState(3,graph_test_req.RoomStateBattleshiplocating), ), events.Enter(3), events.NoAction(app.DefaultPlayerTTL-app.BotShootDelayMax5), util.OnEnd( events.PlaceShips(3), assertion.ARoomState(3, graph_test_req.RoomStateBattleinprocess), ), events.NoAction(app.DefaultPlayerTTL-app.BotShootDelayMax5), assertion.ABattleTurn(3, graph_test_req.PlayerNumberPlayer1), util.OnEnd( events.ShootAll(3), assertion.ARoomState(3, graph_test_req.RoomStateFinished), ), events.NoAction(app.DefaultPlayerTTL-app.BotShootDelayMax*5),

 util.OnEnd( events.NoAction(app.DefaultPlayerTTL), assertion.StartRoomHasNoError(0), assertion.PlayerNotAuthorized(3), assertion.ABattleTurnNil(3), assertion.ARoomStateNotExist(3), ), }, ), table_core.MakeScenario([]table_core.Step{ ... } 

} ```

Internally it also has some kind of shared state to access the result of some assertions or actions.

It has “isolated” scenarios that should be tested with the separate instance of app for each one. And “shared‑instance" scenarios (multiple users on the same app) simulating real world users.

Assertions are executed for each event when defined once. Internally design forces me to redefine assertion of the same kind in case some related behaviour changes. Yes. It can be verbose, but helps me to be sure I nothing missed.

How do you design the table driven tests?

Hope you will find some inspiration in my example. I would be glad to hear about your experience in that direction!

P.S. I extensively use the synctest package. That was a revolution for my project. Since I use the virtual clock all my internal gaming delays/cleanup functions are tested within seconds. It caught production‑only timing bugs by reusing the same timeout configuration in tests. For isolated environment it’s amazing feature.

submitted by /u/you-l-you
[link] [comments]