feat: show actual vs expected on fail

This commit is contained in:
2026-03-21 13:29:12 +00:00
parent d24109e502
commit f89292b57d
2 changed files with 68 additions and 1 deletions
+29 -1
View File
@@ -2,6 +2,7 @@ package mire
import (
"bytes"
"errors"
"fmt"
"io"
"io/fs"
@@ -38,6 +39,15 @@ type testFixtureFiles struct {
outPath string
}
type testMismatchError struct {
expected []byte
actual []byte
}
func (e *testMismatchError) Error() string {
return "output differed"
}
// RunTests replays all scenarios under the configured test directory.
func RunTests(path string) error {
return runTests(path, testIO{
@@ -89,6 +99,10 @@ func runTests(path string, tio testIO) error {
elapsed := time.Since(start)
summary.failed++
output.Fprintf(tio.out, "%s %s (%s): %v\n", output.Label("FAIL", output.Fail), scenario.relPath, formatElapsed(elapsed), err)
var mismatchErr *testMismatchError
if errors.As(err, &mismatchErr) {
writeScenarioMismatch(tio.out, mismatchErr)
}
continue
}
@@ -256,12 +270,26 @@ func replayScenario(scenario testScenario, shellPath string, _ testIO, sandboxCo
}
if !bytes.Equal(got, want) {
return fmt.Errorf("output differed")
return &testMismatchError{
expected: want,
actual: got,
}
}
return nil
}
func writeScenarioMismatch(w io.Writer, mismatch *testMismatchError) {
output.Fprintf(w, "Expected:\n%s", string(mismatch.expected))
if len(mismatch.expected) == 0 || mismatch.expected[len(mismatch.expected)-1] != '\n' {
output.Fprintf(w, "\n")
}
output.Fprintf(w, "Actual:\n%s", string(mismatch.actual))
if len(mismatch.actual) == 0 || mismatch.actual[len(mismatch.actual)-1] != '\n' {
output.Fprintf(w, "\n")
}
}
func trimReplayOutputToMarker(data []byte, shellPath string) ([]byte, error) {
idx := bytes.Index(data, []byte(compareOutputMarker))
if idx == -1 {
+39
View File
@@ -157,6 +157,45 @@ func TestReplayScenarioFailsWhenCompareMarkerMissing(t *testing.T) {
}
}
func TestRunTestsShowsExpectedAndActualForMismatchedScenario(t *testing.T) {
root := t.TempDir()
testDir := filepath.Join(root, "e2e")
testutil.AddFakeRecordDependencies(t, "script")
t.Setenv("FAKE_SCRIPT_ECHO_STDIN", "1")
testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("e2e"))
mustWriteRecordShell(t, testDir)
testutil.WriteScenarioFixtures(t, filepath.Join(testDir, "suite", "spec"), "echo two\n", "echo one\n")
var stdout bytes.Buffer
var stderr bytes.Buffer
err := testutil.WithWorkingDir(t, root, func() error {
return runTests("", testIO{
out: &stdout,
err: &stderr,
})
})
if err != nil {
t.Fatalf("runTests() error = %v", err)
}
if stderr.String() != "" {
t.Fatalf("stderr = %q, want empty", stderr.String())
}
for _, want := range []string{
"RUN suite/spec",
"FAIL suite/spec (",
"output differed",
"Expected:\necho one\n",
"Actual:\necho two\n",
"Summary: total=1 passed=0 failed=1",
} {
if !strings.Contains(stdout.String(), want) {
t.Fatalf("stdout = %q, want substring %q", stdout.String(), want)
}
}
}
func TestDiscoverTestScenariosUsesDisplayRootForRelativePaths(t *testing.T) {
testDir := filepath.Join(t.TempDir(), "e2e")
scopedDir := filepath.Join(testDir, "nested")