Golden files
A golden-file test renders part of your UI and compares the result with a
file saved earlier, called the master. If anything changes, the test
fails and saves what it rendered, so you can see what changed. The test package can compare two kinds of
output:
- Markup: a text description of the rendered object tree, with each object’s type, position, size and text. It is easy to read in a diff.
- Images: the rendered pixels, drawn by Bellui’s software renderer, so no GPU is needed.
A UI to test
func statusCard(title, detail string) core.CanvasObject {
return container.NewVBox(
widget.NewLabelWithStyle(title, bellui.TextAlignLeading, bellui.TextStyle{Bold: true}),
widget.NewLabel(detail),
)
}Comparing markup
func TestStatusCard_Markup(t *testing.T) {
test.NewTempApp(t)
card := statusCard("Backup", "Last run: today")
test.AssertObjectRendersToMarkup(t, "status_card.xml", card)
}test.AssertObjectRendersToMarkup
renders the object at its minimum size and compares the markup with
testdata/status_card.xml, relative to the test’s package folder. The master
for this example looks like this:
<canvas size="107x68">
<content>
<container size="107x68">
<widget size="107x32" type="*widget.Label">
<widget size="107x32" type="*widget.RichText">
<text bold pos="8,8" size="46x16">Backup</text>
</widget>
</widget>
<widget pos="0,36" size="107x32" type="*widget.Label">
<widget size="107x32" type="*widget.RichText">
<text pos="8,8" size="91x16">Last run: today</text>
</widget>
</widget>
</container>
</content>
</canvas>Comparing images
func TestStatusCard_Image(t *testing.T) {
test.NewTempApp(t)
card := statusCard("Backup", "Last run: today")
test.AssertObjectRendersToImage(t, "status_card.png", card)
}test.AssertObjectRendersToImage
does the same with a PNG master. The comparison allows small differences, so
minor anti-aliasing changes between machines do not fail the test.
Creating and updating masters
The first time a test runs there is no master. The test fails, and writes what
it rendered to testdata/failed/. To create or refresh the masters instead,
run the tests with UPDATE_TESTDATA set:
UPDATE_TESTDATA=1 go test ./...Each master is written to testdata/ and the test passes. Look at the new
files before you commit them: a master is only useful if what it shows is
right.
When a comparison fails later, the actual output is written to
testdata/failed/ under the same name, and the failure message gives its
path. Compare it with the master, then either fix the code or rerun with
UPDATE_TESTDATA=1 to accept the change. Add testdata/failed/ to your
.gitignore.
Rendering whole windows
The …Object… functions size a fresh canvas to the object. To check a whole
window, including anything drawn outside one object’s bounds, render its
canvas with test.AssertRendersToMarkup
or test.AssertRendersToImage,
passing w.Canvas() of a test window.
test.NewCanvas has no renderer, so its images come out
blank. The AssertObjectRendersToImage helper sets up a software renderer for
you; for your own canvas use test.NewCanvasWithPainter.When the tests run with the mobile build tag, the helpers first look for a
master under testdata/mobile/ and fall back to the shared one. This lets
widgets that look different on touch screens keep separate masters.