diff --git a/script_test.go b/script_test.go
index 79683655ca2dad12674a48c2ba55207134a8bbe0..a7e9430864f0e9716f5841fd405f1351e2be8cd3 100644
--- a/script_test.go
+++ b/script_test.go
@@ -40,7 +40,7 @@ func TestArgsSuppliesCommandLineArgumentsAsInputToPipeOnePerLine(t *testing.T) {
 	cmd.Env = append(os.Environ(), "SCRIPT_TEST=args")
 	got, err := cmd.Output()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	want := "hello\nworld\n"
 	if string(got) != want {
@@ -69,7 +69,7 @@ func TestBasenameRemovesLeadingPathComponentsFromInputLines(t *testing.T) {
 		want := filepath.Clean(tc.want)
 		got, err := script.Echo(tc.path).Basename().String()
 		if err != nil {
-			t.Error(err)
+			t.Fatal(err)
 		}
 		if want != got {
 			t.Errorf("%q: want %q, got %q", tc.path, want, got)
@@ -237,7 +237,7 @@ func TestDirname_RemovesFilenameComponentFromInputLines(t *testing.T) {
 		want := filepath.Clean(tc.want)
 		got, err := script.Echo(tc.path).Dirname().String()
 		if err != nil {
-			t.Error(err)
+			t.Fatal(err)
 		}
 		if want != got {
 			t.Errorf("%q: want %q, got %q", tc.path, want, got)
@@ -254,7 +254,7 @@ func TestEachLine_FiltersInputThroughSuppliedFunction(t *testing.T) {
 	want := "Hello world\nGoodbye world\n"
 	got, err := q.String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got != want {
 		t.Errorf("want %q, got %q", want, got)
@@ -267,7 +267,7 @@ func TestEchoProducesSuppliedString(t *testing.T) {
 	p := script.Echo(want)
 	got, err := p.String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got != want {
 		t.Errorf("want %q, got %q", want, got)
@@ -280,7 +280,7 @@ func TestEchoReplacesInputWithSuppliedStringWhenUsedAsFilter(t *testing.T) {
 	p := script.Echo("bogus").Echo(want)
 	got, err := p.String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got != want {
 		t.Errorf("want %q, got %q", want, got)
@@ -524,7 +524,7 @@ func TestFreqProducesCorrectFrequencyTableForInput(t *testing.T) {
 	want := "10 apple\n 4 banana\n 4 orange\n 1 kumquat\n"
 	got, err := script.Echo(input).Freq().String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if want != got {
 		t.Error(cmp.Diff(want, got))
@@ -537,7 +537,7 @@ func TestJoinJoinsInputLinesIntoSpaceSeparatedString(t *testing.T) {
 	want := "hello from the join test\n"
 	got, err := script.Echo(input).Join().String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got != want {
 		t.Errorf("want %q, got %q", want, got)
@@ -909,7 +909,7 @@ func TestSHA256Sums_OutputsCorrectHashForEachSpecifiedFile(t *testing.T) {
 	for _, tc := range tcs {
 		got, err := script.ListFiles(tc.testFileName).SHA256Sums().String()
 		if err != nil {
-			t.Error(err)
+			t.Fatal(err)
 		}
 		if got != tc.want {
 			t.Errorf("%q: want %q, got %q", tc.testFileName, tc.want, got)
@@ -937,7 +937,7 @@ func TestExecRunsGoWithNoArgsAndGetsUsageMessagePlusErrorExitStatus2(t *testing.
 		t.Error("want error when command returns a non-zero exit status")
 	}
 	if !strings.Contains(output, "Usage") {
-		t.Fatalf("want output containing the word 'usage', got %q", output)
+		t.Errorf("want output containing the word 'usage', got %q", output)
 	}
 	want := 2
 	got := p.ExitStatus()
@@ -1030,7 +1030,7 @@ func TestIfExists_ProducesErrorPlusNoOutputForNonexistentFile(t *testing.T) {
 	want := ""
 	got, err := script.IfExists("testdata/doesntexist").Echo("hello").String()
 	if err == nil {
-		t.Error("want error")
+		t.Fatal("want error")
 	}
 	if want != got {
 		t.Error(cmp.Diff(want, got))
@@ -1042,7 +1042,7 @@ func TestIfExists_ProducesOutputAndNoErrorWhenFileExists(t *testing.T) {
 	want := "hello"
 	got, err := script.IfExists("testdata/empty.txt").Echo("hello").String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if want != got {
 		t.Error(cmp.Diff(want, got))
@@ -1103,7 +1103,7 @@ func TestReadAutoCloser_ReadsAllDataFromSourceAndClosesItAutomatically(t *testin
 	acr := script.NewReadAutoCloser(input)
 	got, err := io.ReadAll(acr)
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if !cmp.Equal(want, got) {
 		t.Error(cmp.Diff(want, got))
@@ -1137,7 +1137,7 @@ func TestStdinReadsFromProgramStandardInput(t *testing.T) {
 	cmd.Stdin = script.Echo(want)
 	got, err := cmd.Output()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if string(got) != want {
 		t.Errorf("want %q, got %q", want, string(got))
@@ -1151,7 +1151,7 @@ func TestStdoutSendsPipeContentsToConfiguredStandardOutput(t *testing.T) {
 	p := script.File("testdata/hello.txt").WithStdout(buf)
 	wrote, err := p.Stdout()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if wrote != len(want) {
 		t.Errorf("want %d bytes written, got %d", len(want), wrote)
@@ -1177,7 +1177,7 @@ func TestAppendFile_AppendsAllItsInputToSpecifiedFile(t *testing.T) {
 	extra := " and goodbye"
 	wrote, err := script.Echo(extra).AppendFile(path)
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if int(wrote) != len(extra) {
 		t.Errorf("want %d bytes written, got %d", len(extra), int(wrote))
@@ -1185,7 +1185,7 @@ func TestAppendFile_AppendsAllItsInputToSpecifiedFile(t *testing.T) {
 	// check file contains both contents
 	got, err := script.File(path).String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got != orig+extra {
 		t.Errorf("want %q, got %q", orig+extra, got)
@@ -1255,7 +1255,7 @@ func TestSHA256Sum_OutputsCorrectHash(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			got, err := script.Echo(tc.input).SHA256Sum()
 			if err != nil {
-				t.Error(err)
+				t.Fatal(err)
 			}
 			if got != tc.want {
 				t.Errorf("want %q, got %q", tc.want, got)
@@ -1319,7 +1319,7 @@ func TestStringOutputsInputStringUnchanged(t *testing.T) {
 	want := "hello, world"
 	got, err := script.Echo(want).String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if want != got {
 		t.Error(cmp.Diff(want, got))
@@ -1341,14 +1341,14 @@ func TestWriteFile_WritesInputToFileCreatingItIfNecessary(t *testing.T) {
 	path := t.TempDir() + "/" + t.Name()
 	wrote, err := script.Echo(want).WriteFile(path)
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if int(wrote) != len(want) {
 		t.Errorf("want %d bytes written, got %d", len(want), int(wrote))
 	}
 	got, err := script.File(path).String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got != want {
 		t.Errorf("want %q, got %q", want, got)
@@ -1367,17 +1367,17 @@ func TestWriteFile_TruncatesExistingFile(t *testing.T) {
 	}
 	wrote, err := script.Echo(want).WriteFile(path)
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if int(wrote) != len(want) {
 		t.Errorf("want %d bytes written, got %d", len(want), int(wrote))
 	}
 	got, err := script.File(path).String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got == want+"\x00\x00\x00" {
-		t.Fatalf("file not truncated on write")
+		t.Errorf("file not truncated on write")
 	}
 	if got != want {
 		t.Errorf("want %q, got %q", want, got)
@@ -1390,7 +1390,7 @@ func TestWithReader_SetsSuppliedReaderOnPipe(t *testing.T) {
 	p := script.NewPipe().WithReader(strings.NewReader(want))
 	got, err := p.String()
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 	if got != want {
 		t.Errorf("want %q, got %q", want, got)
diff --git a/script_windows_test.go b/script_windows_test.go
index 50ff8a0268418f5dcb03dd9ad59e9ad1dc24ce68..3290d4ec84e186a8362ce6a94b64e0faec82fa5c 100644
--- a/script_windows_test.go
+++ b/script_windows_test.go
@@ -22,7 +22,7 @@ func TestDirnameReturnsExpectedResultsOnPlatformsWithBackslashPathSeparator(t *t
 	for _, tc := range testCases {
 		got, err := script.Echo(tc.path).Dirname().String()
 		if err != nil {
-			t.Error(err)
+			t.Fatal(err)
 		}
 		if tc.want != got {
 			t.Errorf("%q: want %q, got %q", tc.path, tc.want, got)