golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.11k stars 17.68k forks source link

testing: examples with trailing whitespace in multiple lines of output can be confusing #26460

Open joesis opened 6 years ago

joesis commented 6 years ago

Below example fails. Even if I copy the output of go test to the output section, it still fails.

func ExampleTrailingSpace() {
    fmt.Println("abc ")
    fmt.Println("cde")
    // Output:
    //abc
    //cde
}

However, if I remove the second print, it succeeds.

func ExampleTrailingSpace() {
    fmt.Println("abc ")
    // Output:
    //abc
}

Why? Because testing/example.go trims leading and trailing spaces of the whole output, but not every line. Code formatting tools, including gofmt, trims the space of each comment line.

I suggest trimming each line before comparing the output.

joesis commented 6 years ago

It's not uncommon to tabular print in examples. It would be annoying to have to remove the trailing spaces, and more importantly, it's hard to spot what's wrong when the example fails.

fmt.Println("Using Func1:")
for i := 0; i < 10; i++ {
    fmt.Printf("%.3f\t", Func1(i))
}
fmt.Println("")
fmt.Println("Using Func2:")
...
mvdan commented 6 years ago

Even if this is working as intended, I agree that the behavior and failures are confusing.

Are you suggesting to trim only the trailing whitespace from the lines, or also the leading whitespace?

joesis commented 6 years ago

I guess trimming trailing whitespace should be ok, as leading ones can be easily spotted.

josharian commented 6 years ago

See also #6416 and some of the issues linked there

joesis commented 6 years ago

Thanks for the link @josharian. Somehow I didn't find it from closed tickets before creating this one.

If the behavior needs to be kept, a visual clue or message to the users would be ok too.

iwdgo commented 5 years ago

This behavior prevents to provide a testing example of a func which tabulates data using f.i. fmt.Printf("%s\t", s). Although the tab is useless before EOL, it introduces white spaces which StdOut keeps. The trailing spaces cannot be handled by the// Output: of an Example. Removing trailing spaces of every line would help like: lines[i] = strings.TrimRightFunc(s, func(r rune) bool { return unicode.IsSpace(r) })

(edited to add proposal)

mig4 commented 5 years ago

I'm new to Go and I find the idea of examples very useful and testable examples even better, reminds me of doctests from Python. However this underspecified behaviour with whitespace trimming is indeed limiting, as it is currently not possible to cover scenarios where a function's output is expected to contain specific trailing whitespace.

It seems to me it would be much better if the trimming behaviour was instead explicit, allowing the user greater control over what is expected. Perhaps a way to indicate where to trim like:

func ExampleExplicitTrimming() {
    fmt.Printf("this\n\tor that  \n")

    // some way to indicate a character to use as margin
    // so expected output is between the characters

    // Output(margin='|'):
    // |this|
    // |    or that  |
}
mig4 commented 5 years ago

Also #23542

larschri commented 3 years ago

This issue is a bit broader than what the title says. There are many examples of whitespace in output that can't be represented in the example output.

I made a small workaround here https://github.com/larschri/testable-example-output. There is a Normalize function that attempts to implement the same processing that happens to the expected output. I don't know it is complete, but it is sufficient to make the tests pass in that repo. I hope it sheds some light into how this works.

pcj commented 2 years ago

I would really appreciate if example tests displayed failures using something like go-cmp cmp.Diff output. The way it reports now is really a time sink. I often give up on example tests and just write normal ones as a result of the frustration I encounter with them.

mvdan commented 2 years ago

@pcj that's https://github.com/golang/go/issues/45200