-
Notifications
You must be signed in to change notification settings - Fork 369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Go: Update tests to use cmp.Diff instead of reflect.DeepEqual #1244
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely agree with the direction of this change, swapping reflect
out for cmp
, but I think we should be careful to bear in mind Go's Testing Style Guide on this matter (under the heading "Assert Libraries". The "idiomatic go" (I do not like that phrase) way of approaching these things would be to run the cmp.Diff
inline with an if statement. Something like
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Path was unequal (-want, +got): %s", diff)
}
I would be very happy to merge a change that used the pattern suggested by the Go team with the cmp
package instead of reflect
.
language/go/testutils_test.go
Outdated
) | ||
|
||
func equals(t *testing.T, expected, actual interface{}, format string, args ...interface{}) { | ||
allTypes := func(_ reflect.Type) bool { return true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me understand why asserting on all types is the correct thing to do here? What fields do you care about that aren't exported? Are they a thing that actually should be a part of the public API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to make testing easier on unexported types, cmp.Diff
will only compare exported fields by default which is pretty useless if you want to use it to validate your un-exported types in tests.
I am happy to make the suggested change! For dialogue purposes only: I'm not sure I personally agree with the guidance in that wiki. I've been writing go code professionally for a few years now (not that that's some indication that I've been doing it correctly these past years) and most opinions/idiomatic guidance that go suggests, I normally agree with.
I think in most cases, or at least the ones I've predominantly seen, Fatal/Fatalf is the correct choice. Tests are often written procedurally which means that continuing a test after the first error isn't going to test the correct behavior: it's the same reason you return an If the reason you'd want a test to continue after the first error is so that you can assert on the various values of a returned structure, or multiple values not in a structure, it's almost always better to just assert on the structure itself or put the disparate values in a structure, and use
I don't see this as a win if the helpers you write, also just do this for you, like I've done here: func equals(t *testing.T, expected, actual interface{}, format string, args ...interface{})
I think the irony here is that I'm all for consistency, and again I am going to make the changes you requested, but I think consistency, inconsistently applied has very little value |
de9d0cc
to
ac6a523
Compare
PTAL |
49ee530
to
dcdf49f
Compare
Once again, I agree with the primary thrust of this effort, making it easier to debug but disagree with the implementation. To briefly quote from the Assert Libraries documentation:
That is what I think is being violated by this change. It is not clear to me that
The logic of "why are these fields important to be compared" is completely elided when wrapping comparison in something like Function composition is one way to solve problems, but there are many others. The To quote from the
My preference would be to heed the advice of https://go.dev/play/p/02kN3A7712u It advances the objective of making explicit that you're, in this case, only going to succeed if you're comparing If you don't think this is the correct course, instead believing that the correct move is to export all the fields, I would much prefer you used the built in system for achieving such ends, https://go.dev/play/p/z7fpCgve66T What do you think about these options? |
Your example stops the diffing at the level for which you've defined the comparator. Example: Diff (-want,+got):
main.foo(
- {a: "a", b: "b", c: "c"},
+ {a: "1", b: "b", c: "c"},
) versus using Diff (-want,+got):
main.foo{
- a: "a",
+ a: "1",
b: "b",
c: "c",
} Before I continue further, I'm curious to get your take on which output you prefer: 1 or 2? Ultimately I don't have to work in this repository in the day-to-day, so I am less motivated to advocate for QOL improvements that I will not be able to enjoy. |
#2 is probably what I'd do, it has less boilerplate/ |
7e095af
to
d578a30
Compare
@achew22 PTAL |
This is perfect! Thank you so much for your contribution! |
sweet, thanks for the review! |
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [bazel_gazelle](https://togithub.com/bazelbuild/bazel-gazelle) | http_archive | minor | `v0.25.0` -> `v0.26.0` | --- ### Release Notes <details> <summary>bazelbuild/bazel-gazelle</summary> ### [`v0.26.0`](https://togithub.com/bazelbuild/bazel-gazelle/releases/tag/v0.26.0) [Compare Source](https://togithub.com/bazelbuild/bazel-gazelle/compare/v0.25.0...v0.26.0) #### What's Changed - fix(tests): fix gazelle_generation_test expected stderr update by [@​jbedard](https://togithub.com/jbedard) in [bazelbuild/bazel-gazelle#1220 - Add an e2e test confirming no output on success by [@​achew22](https://togithub.com/achew22) in [bazelbuild/bazel-gazelle#1216 - Update extend.md with a practical languages example by [@​Anthony-Bible](https://togithub.com/Anthony-Bible) in [bazelbuild/bazel-gazelle#1222 - fix: Remove gazelle_binary import collision by [@​illicitonion](https://togithub.com/illicitonion) in [bazelbuild/bazel-gazelle#1226 - Broaden label name regex by [@​illicitonion](https://togithub.com/illicitonion) in [bazelbuild/bazel-gazelle#1229 - gazelle_generation_test: redact workspace path from output by [@​dr-dime](https://togithub.com/dr-dime) in [bazelbuild/bazel-gazelle#1231 - Add -print0 to print names of rewritten files by [@​dr-dime](https://togithub.com/dr-dime) in [bazelbuild/bazel-gazelle#1213 - Code Quality Improvements by [@​sluongng](https://togithub.com/sluongng) in [bazelbuild/bazel-gazelle#1197 - Add -strict to exit on build file and directive errors by [@​dr-dime](https://togithub.com/dr-dime) in [bazelbuild/bazel-gazelle#1214 - fix(lang/proto): include imports from different targets by [@​nickgooding](https://togithub.com/nickgooding) in [bazelbuild/bazel-gazelle#1237 - Update rules example in README to v0.25.0 by [@​yujunz](https://togithub.com/yujunz) in [bazelbuild/bazel-gazelle#1240 - Allow static dependency resolution for Gazelle rule by [@​uhthomas](https://togithub.com/uhthomas) in [bazelbuild/bazel-gazelle#1242 - Handle wrapped errors by [@​illicitonion](https://togithub.com/illicitonion) in [bazelbuild/bazel-gazelle#1234 - Go: Update tests to use cmp.Diff instead of reflect.DeepEqual by [@​thempatel](https://togithub.com/thempatel) in [bazelbuild/bazel-gazelle#1244 - Fix startup script manifest resolution with --nolegacy_external_runfiles by [@​jvolkman](https://togithub.com/jvolkman) in [bazelbuild/bazel-gazelle#1247 - Label's package may contain [@​s](https://togithub.com/s) by [@​illicitonion](https://togithub.com/illicitonion) in [bazelbuild/bazel-gazelle#1249 - Trim runfiles prefix consistently by [@​uhthomas](https://togithub.com/uhthomas) in [bazelbuild/bazel-gazelle#1257 - Respect .bazelignore by [@​Whoaa512](https://togithub.com/Whoaa512) in [bazelbuild/bazel-gazelle#1245 - Implement very minimalistic support for go workspaces by [@​HakanSunay](https://togithub.com/HakanSunay) in [bazelbuild/bazel-gazelle#1250 - Fix typo in comment by [@​yujunz](https://togithub.com/yujunz) in [bazelbuild/bazel-gazelle#1270 - Use `patch` from `@bazel_tools//tools/build_defs/repo:utils.bzl` by [@​bozaro](https://togithub.com/bozaro) in [bazelbuild/bazel-gazelle#1269 - Update rules_go to 0.33.0 by [@​fmeum](https://togithub.com/fmeum) in [bazelbuild/bazel-gazelle#1263 - Add support for auth_patterns in go_repository by [@​dmivankov](https://togithub.com/dmivankov) in [bazelbuild/bazel-gazelle#1254 - Sluongng/revert patch by [@​sluongng](https://togithub.com/sluongng) in [bazelbuild/bazel-gazelle#1277 - Stop inferring import path for empty packages by [@​linzhp](https://togithub.com/linzhp) in [bazelbuild/bazel-gazelle#1280 - Don't exclude spaces from the label name regex by [@​illicitonion](https://togithub.com/illicitonion) in [bazelbuild/bazel-gazelle#1271 #### New Contributors - [@​Anthony-Bible](https://togithub.com/Anthony-Bible) made their first contribution in [bazelbuild/bazel-gazelle#1222 - [@​dr-dime](https://togithub.com/dr-dime) made their first contribution in [bazelbuild/bazel-gazelle#1231 - [@​sluongng](https://togithub.com/sluongng) made their first contribution in [bazelbuild/bazel-gazelle#1197 - [@​nickgooding](https://togithub.com/nickgooding) made their first contribution in [bazelbuild/bazel-gazelle#1237 - [@​yujunz](https://togithub.com/yujunz) made their first contribution in [bazelbuild/bazel-gazelle#1240 - [@​uhthomas](https://togithub.com/uhthomas) made their first contribution in [bazelbuild/bazel-gazelle#1242 - [@​thempatel](https://togithub.com/thempatel) made their first contribution in [bazelbuild/bazel-gazelle#1244 - [@​Whoaa512](https://togithub.com/Whoaa512) made their first contribution in [bazelbuild/bazel-gazelle#1245 - [@​HakanSunay](https://togithub.com/HakanSunay) made their first contribution in [bazelbuild/bazel-gazelle#1250 - [@​bozaro](https://togithub.com/bozaro) made their first contribution in [bazelbuild/bazel-gazelle#1269 - [@​fmeum](https://togithub.com/fmeum) made their first contribution in [bazelbuild/bazel-gazelle#1263 - [@​dmivankov](https://togithub.com/dmivankov) made their first contribution in [bazelbuild/bazel-gazelle#1254 **Full Changelog**: bazelbuild/bazel-gazelle@v0.25.0...v0.26.0 #### `WORKSPACE` code load("@​bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_gazelle", sha256 = "501deb3d5695ab658e82f6f6f549ba681ea3ca2a5fb7911154b5aa45596183fa", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.26.0/bazel-gazelle-v0.26.0.tar.gz", "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.26.0/bazel-gazelle-v0.26.0.tar.gz", ], ) load("@​bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") ############################################################ ### Define your own dependencies here using go_repository. ### Else, dependencies declared by rules_go/gazelle will be used. ### The first declaration of an external repository "wins". ############################################################ gazelle_dependencies() </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox. --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-config-validator).
What type of PR is this?
Other
What package or component does this PR mostly affect?
language/go
What does this PR do? Why is it needed?
reflect.DeepEqual
is a poorer chose when choosing to compare test results. For example,DeepEqual
will only compare pointer values using their memory address, rather than the underlying value in the type.This is a pre-factor to make #1243 easier to review (per review feedback)
Which issues(s) does this PR fix?
Fixes #1099
Other notes for review