Repository: amzn/ion-go
Pull request #161 (2020-09-15 22:19:02)

Testify ion-go
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.




Patch:
diff --git a/go.mod b/go.mod
index 8e11425..80b3653 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,7 @@ module github.com/amzn/ion-go
 
 go 1.13
 
-require github.com/google/go-cmp v0.5.0
+require (
+    github.com/google/go-cmp v0.5.0
+    github.com/stretchr/testify v1.6.1
+)
diff --git a/go.sum b/go.sum
index 50d0e6f..d5fe2ea 100644
--- a/go.sum
+++ b/go.sum
@@ -1,4 +1,14 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/ion/symboltoken.go b/ion/symboltoken.go
index a676878..5a1739a 100644
--- a/ion/symboltoken.go
+++ b/ion/symboltoken.go
@@ -103,18 +103,6 @@ func symbolIdentifier(symbolText string) (int64, bool) {
 	return SymbolIDUnknown, false
 }
 
-func getSystemSymbolMapping(symbolTable SymbolTable, symbolName string) (int64, string) {
-	// If we have a symbol name of the form '$n' for some integer n,
-	// then we want to use the corresponding system symbol name.
-	if sid, ok := symbolIdentifier(symbolName); ok {
-		if systemSymbolName, ok := symbolTable.FindByID(uint64(sid)); ok {
-			return sid, systemSymbolName
-		}
-	}
-
-	return SymbolIDUnknown, ""
-}
-
 // NewSymbolTokenBySID will check and return a symbol token if the given id exists in a symbol table,
 // otherwise return a new symbol token.
 func NewSymbolTokenBySID(symbolTable SymbolTable, sid int64) (SymbolToken, error) {


Test patch:
diff --git a/ion/binaryreader_test.go b/ion/binaryreader_test.go
index 27d477e..a78ccdf 100644
--- a/ion/binaryreader_test.go
+++ b/ion/binaryreader_test.go
@@ -20,39 +20,28 @@ import (
 	"math/big"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestReadBadBVMs(t *testing.T) {
 	t.Run("E00200E9", func(t *testing.T) {
 		// Need a good first one or we'll get sent to the text reader.
 		r := NewReaderBytes([]byte{0xE0, 0x01, 0x00, 0xEA, 0xE0, 0x02, 0x00, 0xE9})
-		if r.Next() {
-			t.Errorf("next returned true")
-		}
-		if r.Err() == nil {
-			t.Fatal("err is nil")
-		}
+		assert.False(t, r.Next())
+		require.Error(t, r.Err())
 	})
 
 	t.Run("E00200EA", func(t *testing.T) {
 		r := NewReaderBytes([]byte{0xE0, 0x02, 0x00, 0xEA})
-		if r.Next() {
-			t.Errorf("next returned true")
-		}
-		if r.Err() == nil {
-			t.Fatal("err is nil")
-		}
-
-		uve, ok := r.Err().(*UnsupportedVersionError)
-		if !ok {
-			t.Fatal("err is not an UnsupportedVersionError")
-		}
-		if uve.Major != 2 {
-			t.Errorf("expected major=2, got %v", uve.Major)
-		}
-		if uve.Minor != 0 {
-			t.Errorf("expected minor=0, got %v", uve.Minor)
-		}
+		assert.False(t, r.Next())
+		require.Error(t, r.Err())
+
+		require.IsType(t, &UnsupportedVersionError{}, r.Err())
+		uve := r.Err().(*UnsupportedVersionError)
+		assert.Equal(t, 2, uve.Major)
+		assert.Equal(t, 0, uve.Minor)
 	})
 }
 
@@ -88,12 +77,8 @@ func TestReadBadLST(t *testing.T) {
 		0x0F, // null
 	}
 	r := NewReaderBytes(ion)
-	if r.Next() {
-		t.Fatal("next returned true")
-	}
-	if r.Err() == nil {
-		t.Fatal("err is nil")
-	}
+	require.False(t, r.Next())
+	require.Error(t, r.Err())
 }
 
 func TestReadBinaryLST(t *testing.T) {
@@ -101,49 +86,30 @@ func TestReadBinaryLST(t *testing.T) {
 	_next(t, r, NullType)
 
 	lst := r.SymbolTable()
-	if lst == nil {
-		t.Fatal("symbolTable is nil")
-	}
+	require.NotNil(t, lst)
 
-	if lst.MaxID() != 112 {
-		t.Errorf("expected maxid=112, got %v", lst.MaxID())
-	}
+	assert.Equal(t, 112, int(lst.MaxID()))
 
-	if _, ok := lst.FindByID(109); ok {
-		t.Error("found a symbol for $109")
-	}
+	_, ok := lst.FindByID(109)
+	assert.False(t, ok, "found a symbol for $109")
 
 	sym, ok := lst.FindByID(111)
-	if !ok {
-		t.Fatal("no symbol defined for $111")
-	}
-	if sym != "bar" {
-		t.Errorf("expected $111=bar, got %v", sym)
-	}
+	require.True(t, ok, "no symbol defined for $111")
+	assert.Equal(t, "bar", sym, "expected $111=bar, got %v", sym)
 
 	sym, ok = lst.FindByID(112)
-	if !ok {
-		t.Fatal("no symbol defined for $112")
-	}
-	if sym != "" {
-		t.Errorf("expected $112='', got %v", sym)
-	}
+	require.True(t, ok, "no symbol defined for $112")
+	assert.Empty(t, sym)
 
 	id, ok := lst.FindByName("foo")
-	if !ok {
-		t.Fatal("no id defined for foo")
-	}
-	if id != 110 {
-		t.Errorf("expected foo=$110, got $%v", id)
-	}
+	require.True(t, ok, "no id defined for foo")
+	assert.Equal(t, 110, int(id), "expected foo=$110, got $%v", id)
 
-	if _, ok := lst.FindByID(113); ok {
-		t.Error("found a symbol for $113")
-	}
+	_, ok = lst.FindByID(113)
+	assert.False(t, ok, "found a symbol for $113")
 
-	if _, ok := lst.FindByName("bogus"); ok {
-		t.Error("found a symbol for bogus")
-	}
+	_, ok = lst.FindByName("bogus")
+	assert.False(t, ok, "found a symbol for bogus")
 }
 
 func TestReadBinaryStructs(t *testing.T) {
@@ -276,7 +242,7 @@ func TestReadBinaryFieldNames(t *testing.T) {
 		// }
 	})
 	r.Next()
-	r.StepIn()
+	require.NoError(t, r.StepIn())
 	_nextF(t, r, &SymbolToken{Text: nil, LocalSID: 0}, false, false)
 	_nextF(t, r, &SymbolToken{Text: newString("$ion"), LocalSID: 1}, false, false)
 	_nextF(t, r, &SymbolToken{Text: newString("foo"), LocalSID: 110}, false, false)
diff --git a/ion/binarywriter_test.go b/ion/binarywriter_test.go
index e25721c..bb8b92e 100644
--- a/ion/binarywriter_test.go
+++ b/ion/binarywriter_test.go
@@ -24,6 +24,9 @@ import (
 	"strings"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestWriteBinaryStruct(t *testing.T) {
@@ -35,20 +38,20 @@ func TestWriteBinaryStruct(t *testing.T) {
 		// }
 	}
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.BeginStruct()
-		w.EndStruct()
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.EndStruct())
 
-		w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown})
-		w.BeginStruct()
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginStruct())
 		{
-			w.FieldName("name")
-			w.Annotation(SymbolToken{Text: newString("bar"), LocalSID: SymbolIDUnknown})
-			w.WriteNull()
+			assert.NoError(t, w.FieldName("name"))
+			assert.NoError(t, w.Annotation(SymbolToken{Text: newString("bar"), LocalSID: SymbolIDUnknown}))
+			assert.NoError(t, w.WriteNull())
 
-			w.FieldName("max_id")
-			w.WriteInt(0)
+			assert.NoError(t, w.FieldName("max_id"))
+			assert.NoError(t, w.WriteInt(0))
 		}
-		w.EndStruct()
+		assert.NoError(t, w.EndStruct())
 	})
 }
 
@@ -61,18 +64,18 @@ func TestWriteBinarySexp(t *testing.T) {
 		// )
 	}
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.BeginSexp()
-		w.EndSexp()
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.EndSexp())
 
-		w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown})
-		w.BeginSexp()
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginSexp())
 		{
-			w.Annotation(SymbolToken{Text: newString("bar"), LocalSID: SymbolIDUnknown})
-			w.WriteNull()
+			assert.NoError(t, w.Annotation(SymbolToken{Text: newString("bar"), LocalSID: SymbolIDUnknown}))
+			assert.NoError(t, w.WriteNull())
 
-			w.WriteInt(0)
+			assert.NoError(t, w.WriteInt(0))
 		}
-		w.EndSexp()
+		assert.NoError(t, w.EndSexp())
 	})
 }
 
@@ -85,18 +88,18 @@ func TestWriteBinaryList(t *testing.T) {
 		// ]
 	}
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.BeginList()
-		w.EndList()
+		assert.NoError(t, w.BeginList())
+		assert.NoError(t, w.EndList())
 
-		w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown})
-		w.BeginList()
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginList())
 		{
-			w.Annotation(SymbolToken{Text: newString("bar"), LocalSID: SymbolIDUnknown})
-			w.WriteNull()
+			assert.NoError(t, w.Annotation(SymbolToken{Text: newString("bar"), LocalSID: SymbolIDUnknown}))
+			assert.NoError(t, w.WriteNull())
 
-			w.WriteInt(0)
+			assert.NoError(t, w.WriteInt(0))
 		}
-		w.EndList()
+		assert.NoError(t, w.EndList())
 	})
 }
 
@@ -106,8 +109,8 @@ func TestWriteBinaryBlob(t *testing.T) {
 		0xAB, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd',
 	}
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteBlob([]byte{})
-		w.WriteBlob([]byte("Hello World"))
+		assert.NoError(t, w.WriteBlob([]byte{}))
+		assert.NoError(t, w.WriteBlob([]byte("Hello World")))
 	})
 }
 
@@ -117,7 +120,7 @@ func TestWriteLargeBinaryBlob(t *testing.T) {
 	eval[1] = 0x01
 	eval[2] = 0x80
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteBlob(make([]byte, 128))
+		assert.NoError(t, w.WriteBlob(make([]byte, 128)))
 	})
 }
 
@@ -127,8 +130,8 @@ func TestWriteBinaryClob(t *testing.T) {
 		0x9B, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd',
 	}
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteClob([]byte{})
-		w.WriteClob([]byte("Hello World"))
+		assert.NoError(t, w.WriteClob([]byte{}))
+		assert.NoError(t, w.WriteClob([]byte("Hello World")))
 	})
 }
 
@@ -141,10 +144,10 @@ func TestWriteBinaryString(t *testing.T) {
 		0x84, 0xE0, 0x01, 0x00, 0xEA,
 	}
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteString("")
-		w.WriteString("Hello World")
-		w.WriteString("Hello World But Even Longer")
-		w.WriteString("\xE0\x01\x00\xEA")
+		assert.NoError(t, w.WriteString(""))
+		assert.NoError(t, w.WriteString("Hello World"))
+		assert.NoError(t, w.WriteString("Hello World But Even Longer"))
+		assert.NoError(t, w.WriteString("\xE0\x01\x00\xEA"))
 	})
 }
 
@@ -157,11 +160,11 @@ func TestWriteBinarySymbol(t *testing.T) {
 		0x74, 0xFF, 0xFF, 0xFF, 0xFF, // $4294967295
 	}
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteSymbol("$ion")
-		w.WriteSymbol("name")
-		w.WriteSymbol("version")
-		w.WriteSymbol("$ion_shared_symbol_table")
-		w.WriteSymbol("$4294967295")
+		assert.NoError(t, w.WriteSymbol("$ion"))
+		assert.NoError(t, w.WriteSymbol("name"))
+		assert.NoError(t, w.WriteSymbol("version"))
+		assert.NoError(t, w.WriteSymbol("$ion_shared_symbol_table"))
+		assert.NoError(t, w.WriteSymbol("$4294967295"))
 	})
 }
 
@@ -183,8 +186,8 @@ func TestWriteBinaryTimestamp(t *testing.T) {
 	nowish, _ := NewTimestampFromStr("2019-08-04T18:15:43.863494+10:00", TimestampPrecisionNanosecond, TimezoneLocal)
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteTimestamp(NewTimestamp(time.Time{}, TimestampPrecisionNanosecond, TimezoneUTC))
-		w.WriteTimestamp(nowish)
+		assert.NoError(t, w.WriteTimestamp(NewTimestamp(time.Time{}, TimestampPrecisionNanosecond, TimezoneUTC)))
+		assert.NoError(t, w.WriteTimestamp(nowish))
 	})
 }
 
@@ -200,13 +203,13 @@ func TestWriteBinaryDecimal(t *testing.T) {
 	}
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteDecimal(MustParseDecimal("0."))
-		w.WriteDecimal(MustParseDecimal("0.0"))
-		w.WriteDecimal(MustParseDecimal("0.000"))
-		w.WriteDecimal(MustParseDecimal("1.000"))
-		w.WriteDecimal(MustParseDecimal("-1.000"))
-		w.WriteDecimal(MustParseDecimal("1d100"))
-		w.WriteDecimal(MustParseDecimal("-1d100"))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("0.")))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("0.0")))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("0.000")))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("1.000")))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("-1.000")))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("1d100")))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("-1d100")))
 	})
 }
 
@@ -221,12 +224,12 @@ func TestWriteBinaryFloats(t *testing.T) {
 	}
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteFloat(0)
-		w.WriteFloat(math.MaxFloat64)
-		w.WriteFloat(-math.MaxFloat64)
-		w.WriteFloat(math.Inf(1))
-		w.WriteFloat(math.Inf(-1))
-		w.WriteFloat(math.NaN())
+		assert.NoError(t, w.WriteFloat(0))
+		assert.NoError(t, w.WriteFloat(math.MaxFloat64))
+		assert.NoError(t, w.WriteFloat(-math.MaxFloat64))
+		assert.NoError(t, w.WriteFloat(math.Inf(1)))
+		assert.NoError(t, w.WriteFloat(math.Inf(-1)))
+		assert.NoError(t, w.WriteFloat(math.NaN()))
 	})
 }
 
@@ -239,10 +242,10 @@ func TestWriteBinaryBigInts(t *testing.T) {
 	}
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteBigInt(big.NewInt(0))
-		w.WriteBigInt(big.NewInt(0xFF))
-		w.WriteBigInt(big.NewInt(-0xFF))
-		w.WriteBigInt(new(big.Int).SetBytes([]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}))
+		assert.NoError(t, w.WriteBigInt(big.NewInt(0)))
+		assert.NoError(t, w.WriteBigInt(big.NewInt(0xFF)))
+		assert.NoError(t, w.WriteBigInt(big.NewInt(-0xFF)))
+		assert.NoError(t, w.WriteBigInt(new(big.Int).SetBytes([]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})))
 	})
 }
 
@@ -255,7 +258,7 @@ func TestWriteBinaryReallyBigInts(t *testing.T) {
 	testBinaryWriter(t, eval, func(w Writer) {
 		i := new(big.Int)
 		i = i.SetBit(i, 1023, 1)
-		w.WriteBigInt(i)
+		assert.NoError(t, w.WriteBigInt(i))
 	})
 }
 
@@ -270,12 +273,12 @@ func TestWriteBinaryInts(t *testing.T) {
 	}
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteInt(0)
-		w.WriteInt(0xFF)
-		w.WriteInt(-0xFF)
-		w.WriteInt(0xFFFF)
-		w.WriteInt(-0xFFFFFF)
-		w.WriteInt(math.MaxInt64)
+		assert.NoError(t, w.WriteInt(0))
+		assert.NoError(t, w.WriteInt(0xFF))
+		assert.NoError(t, w.WriteInt(-0xFF))
+		assert.NoError(t, w.WriteInt(0xFFFF))
+		assert.NoError(t, w.WriteInt(-0xFFFFFF))
+		assert.NoError(t, w.WriteInt(math.MaxInt64))
 	})
 }
 
@@ -289,8 +292,8 @@ func TestWriteBinaryBoolAnnotated(t *testing.T) {
 	}
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.Annotations(SymbolToken{Text: newString("name"), LocalSID: 4}, SymbolToken{Text: newString("version"), LocalSID: 5})
-		w.WriteBool(false)
+		assert.NoError(t, w.Annotations(SymbolToken{Text: newString("name"), LocalSID: 4}, SymbolToken{Text: newString("version"), LocalSID: 5}))
+		assert.NoError(t, w.WriteBool(false))
 	})
 }
 
@@ -301,8 +304,8 @@ func TestWriteBinaryBools(t *testing.T) {
 	}
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteBool(false)
-		w.WriteBool(true)
+		assert.NoError(t, w.WriteBool(false))
+		assert.NoError(t, w.WriteBool(true))
 	})
 }
 
@@ -325,19 +328,19 @@ func TestWriteBinaryNulls(t *testing.T) {
 	}
 
 	testBinaryWriter(t, eval, func(w Writer) {
-		w.WriteNull()
-		w.WriteNullType(BoolType)
-		w.WriteNullType(IntType)
-		w.WriteNullType(FloatType)
-		w.WriteNullType(DecimalType)
-		w.WriteNullType(TimestampType)
-		w.WriteNullType(SymbolType)
-		w.WriteNullType(StringType)
-		w.WriteNullType(ClobType)
-		w.WriteNullType(BlobType)
-		w.WriteNullType(ListType)
-		w.WriteNullType(SexpType)
-		w.WriteNullType(StructType)
+		assert.NoError(t, w.WriteNull())
+		assert.NoError(t, w.WriteNullType(BoolType))
+		assert.NoError(t, w.WriteNullType(IntType))
+		assert.NoError(t, w.WriteNullType(FloatType))
+		assert.NoError(t, w.WriteNullType(DecimalType))
+		assert.NoError(t, w.WriteNullType(TimestampType))
+		assert.NoError(t, w.WriteNullType(SymbolType))
+		assert.NoError(t, w.WriteNullType(StringType))
+		assert.NoError(t, w.WriteNullType(ClobType))
+		assert.NoError(t, w.WriteNullType(BlobType))
+		assert.NoError(t, w.WriteNullType(ListType))
+		assert.NoError(t, w.WriteNullType(SexpType))
+		assert.NoError(t, w.WriteNullType(StructType))
 	})
 }
 
@@ -361,9 +364,7 @@ func testBinaryWriter(t *testing.T, eval []byte, f func(w Writer)) {
 	}
 	eval = append(prefix, eval...)
 
-	if !bytes.Equal(val, eval) {
-		t.Errorf("expected %v, got %v", fmtbytes(eval), fmtbytes(val))
-	}
+	assert.True(t, bytes.Equal(val, eval), "expected %v, got %v", fmtbytes(eval), fmtbytes(val))
 }
 
 func fmtbytes(bs []byte) string {
@@ -397,9 +398,7 @@ func writeBinary(t *testing.T, f func(w Writer)) []byte {
 
 	f(w)
 
-	if err := w.Finish(); err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, w.Finish())
 
 	return buf.Bytes()
 }
diff --git a/ion/bits_test.go b/ion/bits_test.go
index 8ae09db..109e8f9 100644
--- a/ion/bits_test.go
+++ b/ion/bits_test.go
@@ -22,20 +22,18 @@ import (
 	"math/big"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestAppendUint(t *testing.T) {
 	test := func(val uint64, elen uint64, ebits []byte) {
 		t.Run(fmt.Sprintf("%x", val), func(t *testing.T) {
 			length := uintLen(val)
-			if length != elen {
-				t.Errorf("expected length=%v, got length=%v", elen, length)
-			}
+			assert.Equal(t, elen, length)
 
 			bits := appendUint(nil, val)
-			if !bytes.Equal(bits, ebits) {
-				t.Errorf("expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
-			}
+			assert.True(t, bytes.Equal(bits, ebits), "expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
 		})
 	}
 
@@ -49,14 +47,10 @@ func TestAppendInt(t *testing.T) {
 	test := func(val int64, elen uint64, ebits []byte) {
 		t.Run(fmt.Sprintf("%x", val), func(t *testing.T) {
 			length := intLen(val)
-			if length != elen {
-				t.Errorf("expected length=%v, got length=%v", elen, length)
-			}
+			assert.Equal(t, elen, length)
 
 			bits := appendInt(nil, val)
-			if !bytes.Equal(bits, ebits) {
-				t.Errorf("expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
-			}
+			assert.True(t, bytes.Equal(bits, ebits), "expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
 		})
 	}
 
@@ -79,14 +73,10 @@ func TestAppendBigInt(t *testing.T) {
 	test := func(val *big.Int, elen uint64, ebits []byte) {
 		t.Run(fmt.Sprintf("%x", val), func(t *testing.T) {
 			length := bigIntLen(val)
-			if length != elen {
-				t.Errorf("expected length=%v, got length=%v", elen, length)
-			}
+			assert.Equal(t, elen, length)
 
 			bits := appendBigInt(nil, val)
-			if !bytes.Equal(bits, ebits) {
-				t.Errorf("expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
-			}
+			assert.True(t, bytes.Equal(bits, ebits), "expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
 		})
 	}
 
@@ -105,14 +95,10 @@ func TestAppendVarUint(t *testing.T) {
 	test := func(val uint64, elen uint64, ebits []byte) {
 		t.Run(fmt.Sprintf("%x", val), func(t *testing.T) {
 			length := varUintLen(val)
-			if length != elen {
-				t.Errorf("expected length=%v, got length=%v", elen, length)
-			}
+			assert.Equal(t, elen, length)
 
 			bits := appendVarUint(nil, val)
-			if !bytes.Equal(bits, ebits) {
-				t.Errorf("expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
-			}
+			assert.True(t, bytes.Equal(bits, ebits), "expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
 		})
 	}
 
@@ -130,14 +116,10 @@ func TestAppendVarInt(t *testing.T) {
 	test := func(val int64, elen uint64, ebits []byte) {
 		t.Run(fmt.Sprintf("%x", val), func(t *testing.T) {
 			length := varIntLen(val)
-			if length != elen {
-				t.Errorf("expected length=%v, got length=%v", elen, length)
-			}
+			assert.Equal(t, elen, length)
 
 			bits := appendVarInt(nil, val)
-			if !bytes.Equal(bits, ebits) {
-				t.Errorf("expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
-			}
+			assert.True(t, bytes.Equal(bits, ebits), "expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
 		})
 	}
 
@@ -167,14 +149,10 @@ func TestAppendTag(t *testing.T) {
 	test := func(code byte, vlen uint64, elen uint64, ebits []byte) {
 		t.Run(fmt.Sprintf("(%x,%v)", code, vlen), func(t *testing.T) {
 			length := tagLen(vlen)
-			if length != elen {
-				t.Errorf("expected length=%v, got length=%v", elen, length)
-			}
+			assert.Equal(t, elen, length)
 
 			bits := appendTag(nil, code, vlen)
-			if !bytes.Equal(bits, ebits) {
-				t.Errorf("expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
-			}
+			assert.True(t, bytes.Equal(bits, ebits), "expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
 		})
 	}
 
@@ -192,14 +170,10 @@ func TestAppendTimestamp(t *testing.T) {
 			val.dateTime = val.dateTime.In(time.UTC)
 
 			length := timestampLen(offset, val)
-			if length != elen {
-				t.Errorf("expected length=%v, got length=%v", elen, length)
-			}
+			assert.Equal(t, elen, length)
 
 			bits := appendTimestamp(nil, offset, val)
-			if !bytes.Equal(bits, ebits) {
-				t.Errorf("expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
-			}
+			assert.True(t, bytes.Equal(bits, ebits), "expected %v, got %v", fmtbytes(ebits), fmtbytes(bits))
 		})
 	}
 
diff --git a/ion/bitstream_test.go b/ion/bitstream_test.go
index 86e745c..c5baf00 100644
--- a/ion/bitstream_test.go
+++ b/ion/bitstream_test.go
@@ -17,6 +17,9 @@ package ion
 
 import (
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestBitstream(t *testing.T) {
@@ -45,44 +48,28 @@ func TestBitstream(t *testing.T) {
 	b.InitBytes(ion)
 
 	next := func(code bitcode, null bool, length uint64) {
-		if err := b.Next(); err != nil {
-			t.Fatal(err)
-		}
-		if b.Code() != code {
-			t.Errorf("expected code=%v, got %v", code, b.Code())
-		}
-		if b.IsNull() != null {
-			t.Errorf("expected null=%v, got %v", null, b.IsNull())
-		}
-		if b.Len() != length {
-			t.Errorf("expected length=%v, got %v", length, b.Len())
-		}
+		require.NoError(t, b.Next())
+		assert.Equal(t, code, b.Code())
+		assert.Equal(t, null, b.IsNull())
+		assert.Equal(t, length, b.Len())
 	}
 
 	fieldid := func(eid uint64) {
 		id, err := b.ReadFieldID()
-		if err != nil {
-			t.Fatal(err)
-		}
-		if id != eid {
-			t.Errorf("expected %v, got %v", eid, id)
-		}
+		require.NoError(t, err)
+		assert.Equal(t, eid, id)
 	}
 
 	next(bitcodeBVM, false, 3)
 	maj, min, err := b.ReadBVM()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	if maj != 1 && min != 0 {
 		t.Errorf("expected $ion_1.0, got $ion_%v.%v", maj, min)
 	}
 
 	next(bitcodeAnnotation, false, 31)
 	as, err := b.ReadAnnotations(V1SystemSymbolTable)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	if len(as) != 1 || as[0].LocalSID != 3 { // $ion_symbol_table
 		t.Errorf("expected [3], got %v", as)
 	}
@@ -98,19 +85,15 @@ func TestBitstream(t *testing.T) {
 		{
 			next(bitcodeStruct, false, 13)
 		}
-		if err := b.StepOut(); err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, b.StepOut())
 
 		next(bitcodeFieldID, false, 0)
-		// fieldid(7) // symbols
+		fieldid(7) // symbols
 
 		next(bitcodeList, false, 8)
 		next(bitcodeEOF, false, 0)
 	}
-	if err := b.StepOut(); err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, b.StepOut())
 
 	next(bitcodeStruct, false, 0)
 	next(bitcodeAnnotation, false, 10)
@@ -120,10 +103,7 @@ func TestBitstream(t *testing.T) {
 
 func TestBitcodeString(t *testing.T) {
 	for i := bitcodeNone; i <= bitcodeAnnotation+1; i++ {
-		str := i.String()
-		if str == "" {
-			t.Errorf("expected non-empty string for bitcode %v", uint8(i))
-		}
+		assert.NotEmpty(t, i.String(), "expected non-empty string for bitcode %v", uint8(i))
 	}
 }
 
@@ -132,21 +112,15 @@ func TestBinaryReadTimestamp(t *testing.T) {
 		t.Run(expectedValue, func(t *testing.T) {
 			b := bitstream{}
 			b.InitBytes(ion)
-			b.Next()
+			assert.NoError(t, b.Next())
 
 			val, err := b.ReadTimestamp()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
 			expectedTimestamp, err := NewTimestampFromStr(expectedValue, expectedPrecision, expectedKind)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
-			if !val.Equal(expectedTimestamp) {
-				t.Errorf("expected %v, got %v", expectedTimestamp, val)
-			}
+			assert.True(t, val.Equal(expectedTimestamp), "expected %v, got %v", expectedTimestamp, val)
 		})
 	}
 
diff --git a/ion/buf_test.go b/ion/buf_test.go
index 42edf24..072ff5d 100644
--- a/ion/buf_test.go
+++ b/ion/buf_test.go
@@ -18,6 +18,9 @@ package ion
 import (
 	"bytes"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestBufnode(t *testing.T) {
@@ -58,9 +61,8 @@ func TestBufnode(t *testing.T) {
 	}
 
 	buf := bytes.Buffer{}
-	if err := root.EmitTo(&buf); err != nil {
-		t.Fatal(err)
-	}
+
+	require.NoError(t, root.EmitTo(&buf))
 
 	val := buf.Bytes()
 	eval := []byte{
@@ -88,7 +90,5 @@ func TestBufnode(t *testing.T) {
 		// }
 	}
 
-	if !bytes.Equal(val, eval) {
-		t.Errorf("expected %v, got %v", fmtbytes(eval), fmtbytes(val))
-	}
+	assert.True(t, bytes.Equal(val, eval), "expected %v, got %v", fmtbytes(eval), fmtbytes(val))
 }
diff --git a/ion/catalog_test.go b/ion/catalog_test.go
index 2122eab..21abb42 100644
--- a/ion/catalog_test.go
+++ b/ion/catalog_test.go
@@ -19,6 +19,9 @@ import (
 	"bytes"
 	"fmt"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 type Item struct {
@@ -39,16 +42,15 @@ func TestCatalog(t *testing.T) {
 	out := NewBinaryWriter(&buf, sst)
 
 	for i := 0; i < 10; i++ {
-		out.Annotation(SymbolToken{Text: newString("item"), LocalSID: SymbolIDUnknown})
-		MarshalTo(out, &Item{
-			ID:          i,
-			Name:        fmt.Sprintf("Item %v", i),
-			Description: fmt.Sprintf("The %vth test item", i),
-		})
-	}
-	if err := out.Finish(); err != nil {
-		t.Fatal(err)
+		assert.NoError(t, out.Annotation(SymbolToken{Text: newString("item"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t,
+			MarshalTo(out, &Item{
+				ID:          i,
+				Name:        fmt.Sprintf("Item %v", i),
+				Description: fmt.Sprintf("The %vth test item", i),
+			}))
 	}
+	require.NoError(t, out.Finish())
 
 	bs := buf.Bytes()
 
@@ -62,16 +64,10 @@ func TestCatalog(t *testing.T) {
 		if err == ErrNoInput {
 			break
 		}
-		if err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, err)
 
-		if item.ID != i {
-			t.Errorf("expected id=%v, got %v", i, item.ID)
-		}
+		assert.Equal(t, i, item.ID)
 	}
 
-	if i != 10 {
-		t.Errorf("expected i=10, got %v", i)
-	}
+	assert.Equal(t, 10, i)
 }
diff --git a/ion/cmp_test.go b/ion/cmp_test.go
index 63ae130..7c3ffc8 100644
--- a/ion/cmp_test.go
+++ b/ion/cmp_test.go
@@ -134,13 +134,21 @@ func cmpTimestamps(thisValue, otherValue interface{}) bool {
 }
 
 func cmpSymbols(thisValue, otherValue interface{}) bool {
-	val1 := thisValue.(*SymbolToken)
-	val2 := otherValue.(*SymbolToken)
+	if thisValue == nil || otherValue == nil {
+		return thisValue == nil && otherValue == nil
+	}
 
-	if val1 == nil || val2 == nil {
-		return val1 == nil && val2 == nil
+	if val1, ok := thisValue.(SymbolToken); ok {
+		if val2, ok := otherValue.(SymbolToken); ok {
+			return val1.Equal(&val2)
+		}
+	} else if val1, ok := thisValue.(*SymbolToken); ok {
+		if val2, ok := otherValue.(*SymbolToken); ok {
+			return val1.Equal(val2)
+		}
 	}
-	return val1.Equal(val2)
+
+	return false
 }
 
 func cmpValueSlices(thisValues, otherValues []interface{}) bool {
diff --git a/ion/decimal_test.go b/ion/decimal_test.go
index a2bc8fc..f2e66a1 100644
--- a/ion/decimal_test.go
+++ b/ion/decimal_test.go
@@ -19,6 +19,9 @@ import (
 	"fmt"
 	"math/big"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestDecimalToString(t *testing.T) {
@@ -29,9 +32,7 @@ func TestDecimalToString(t *testing.T) {
 				scale: scale,
 			}
 			actual := d.String()
-			if actual != expected {
-				t.Errorf("expected '%v', got '%v'", expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 		})
 	}
 
@@ -68,16 +69,10 @@ func TestParseDecimal(t *testing.T) {
 	test := func(in string, n *big.Int, scale int32) {
 		t.Run(in, func(t *testing.T) {
 			d, err := ParseDecimal(in)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
-			if n.Cmp(d.n) != 0 {
-				t.Errorf("wrong n; expected %v, got %v", n, d.n)
-			}
-			if scale != d.scale {
-				t.Errorf("wrong scale; expected %v, got %v", scale, d.scale)
-			}
+			assert.True(t, n.Cmp(d.n) == 0, "wrong n; expected %v, got %v", n, d.n)
+			assert.Equal(t, scale, d.scale)
 		})
 	}
 
@@ -114,9 +109,7 @@ func testUnaryOp(t *testing.T, a, e string, op *unaryop) {
 		aa, _ := ParseDecimal(a)
 		ee, _ := ParseDecimal(e)
 		actual := op.fun(aa)
-		if !actual.Equal(ee) {
-			t.Errorf("expected %v, got %v", ee, actual)
-		}
+		assert.True(t, actual.Equal(ee), "expected %v, got %v", ee, actual)
 	})
 }
 
@@ -149,12 +142,8 @@ func TestTrunc(t *testing.T) {
 		t.Run(fmt.Sprintf("trunc(%v)=%v", a, eval), func(t *testing.T) {
 			aa := MustParseDecimal(a)
 			val, err := aa.trunc()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			require.NoError(t, err)
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -173,12 +162,8 @@ func TestRound(t *testing.T) {
 		t.Run(fmt.Sprintf("trunc(%v)=%v", a, eval), func(t *testing.T) {
 			aa := MustParseDecimal(a)
 			val, err := aa.round()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			require.NoError(t, err)
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -213,9 +198,7 @@ func TestShiftL(t *testing.T) {
 		aa, _ := ParseDecimal(a)
 		ee, _ := ParseDecimal(e)
 		actual := aa.ShiftL(b)
-		if !actual.Equal(ee) {
-			t.Errorf("expected %v, got %v", ee, actual)
-		}
+		assert.True(t, actual.Equal(ee), "expected %v, got %v", ee, actual)
 	}
 
 	test("0", 10, "0")
@@ -230,9 +213,7 @@ func TestShiftR(t *testing.T) {
 		aa, _ := ParseDecimal(a)
 		ee, _ := ParseDecimal(e)
 		actual := aa.ShiftR(b)
-		if !actual.Equal(ee) {
-			t.Errorf("expected %v, got %v", ee, actual)
-		}
+		assert.True(t, actual.Equal(ee), "expected %v, got %v", ee, actual)
 	}
 
 	test("0", 10, "0")
@@ -253,9 +234,7 @@ func testBinaryOp(t *testing.T, a, b, e string, op *binop) {
 		ee, _ := ParseDecimal(e)
 
 		actual := op.fun(aa, bb)
-		if !actual.Equal(ee) {
-			t.Errorf("expected %v, got %v", ee, actual)
-		}
+		assert.True(t, actual.Equal(ee), "expected %v, got %v", ee, actual)
 	})
 }
 
@@ -307,9 +286,7 @@ func TestTruncate(t *testing.T) {
 		t.Run(fmt.Sprintf("trunc(%v,%v)", a, p), func(t *testing.T) {
 			aa := MustParseDecimal(a)
 			actual := aa.Truncate(p).String()
-			if actual != expected {
-				t.Errorf("expected %v, got %v", expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 		})
 	}
 
@@ -328,9 +305,7 @@ func TestCmp(t *testing.T) {
 			ad, _ := ParseDecimal(a)
 			bd, _ := ParseDecimal(b)
 			actual := ad.Cmp(bd)
-			if actual != expected {
-				t.Errorf("expected %v, got %v", expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 		})
 	}
 
@@ -352,7 +327,5 @@ func TestCmp(t *testing.T) {
 func TestUpscale(t *testing.T) {
 	d, _ := ParseDecimal("1d1")
 	actual := d.upscale(4).String()
-	if actual != "10.0000" {
-		t.Errorf("expected 10.0000, got %v", actual)
-	}
+	assert.Equal(t, "10.0000", actual)
 }
diff --git a/ion/integration_test.go b/ion/integration_test.go
index 0bfd7f8..556cd42 100644
--- a/ion/integration_test.go
+++ b/ion/integration_test.go
@@ -24,6 +24,9 @@ import (
 	"reflect"
 	"strings"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 const goodPath = "../ion-tests/iontestdata/good"
@@ -177,10 +180,8 @@ func testBinaryRoundTrip(t *testing.T, fp string) {
 		reader2.Next()
 		i2 := readCurrentValue(t, reader2)
 
-		if !i1.equal(i2) {
-			t.Errorf("Failed on %s round trip. Binary reader has %v "+
-				"where the value in Text reader is %v", fp, i1.value, i2.value)
-		}
+		assert.True(t, i1.equal(i2), "Failed on %s round trip. Binary reader has %v "+
+			"where the value in Text reader is %v", fp, i1.value, i2.value)
 	}
 }
 
@@ -204,10 +205,8 @@ func testTextRoundTrip(t *testing.T, fp string) {
 		reader2.Next()
 		i2 := readCurrentValue(t, reader2)
 
-		if !i1.equal(i2) {
-			t.Errorf("Failed on %s round trip. Text reader has %v "+
-				"where the value in Binary reader is %v", fp, i1.value, i2.value)
-		}
+		assert.True(t, i1.equal(i2), "Failed on %s round trip. Text reader has %v "+
+			"where the value in Binary reader is %v", fp, i1.value, i2.value)
 	}
 }
 
@@ -217,10 +216,7 @@ func encodeAsTextIon(t *testing.T, data []byte, st ...SharedSymbolTable) strings
 	str := strings.Builder{}
 	txtWriter := NewTextWriterOpts(&str, 0, st...)
 	writeFromReaderToWriter(t, reader, txtWriter)
-	err := txtWriter.Finish()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, txtWriter.Finish())
 	return str
 }
 
@@ -230,44 +226,39 @@ func encodeAsBinaryIon(t *testing.T, data []byte, st ...SharedSymbolTable) bytes
 	buf := bytes.Buffer{}
 	binWriter := NewBinaryWriter(&buf, st...)
 	writeFromReaderToWriter(t, reader, binWriter)
-	err := binWriter.Finish()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, binWriter.Finish())
 	return buf
 }
 
 // Reads Ion values from the provided file, verifying that an
 // error is or is not encountered as indicated by errorExpected.
 func testLoadFile(t *testing.T, errorExpected bool, fp string) {
-	file, er := os.Open(fp)
-	if er != nil {
-		t.Fatal(er)
-	}
+	file, err := os.Open(fp)
+	require.NoError(t, err)
 
 	r := NewReader(file)
-	err := testInvalidReader(t, r)
+	err = testInvalidReader(r)
+
+	if errorExpected {
+		require.True(t, r.Err() != nil || err != nil, "Should have failed loading \""+fp+"\".")
 
-	if errorExpected && r.Err() == nil && err == nil {
-		t.Fatal("Should have failed loading \"" + fp + "\".")
-	} else if !errorExpected && (r.Err() != nil || err != nil) {
-		t.Fatal("Failed loading \"" + fp + "\" : " + r.Err().Error())
-	} else {
 		errMsg := "no"
 		if r.Err() != nil {
 			errMsg = r.Err().Error()
+		} else if err != nil {
+			errMsg = err.Error()
 		}
 		t.Log("Test passed for " + fp + " with \"" + errMsg + "\" error.")
+	} else {
+		require.NoError(t, r.Err(), "Failed loading \""+fp+"\"")
+		require.NoError(t, err, "Failed loading \""+fp+"\"")
 	}
 
-	err = file.Close()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, file.Close())
 }
 
 // Traverse the reader and check if it is an invalid reader, containing malformed Ion values.
-func testInvalidReader(t *testing.T, r Reader) error {
+func testInvalidReader(r Reader) error {
 	for r.Next() {
 		switch r.Type() {
 		case StructType, ListType, SexpType:
@@ -278,7 +269,7 @@ func testInvalidReader(t *testing.T, r Reader) error {
 			if err != nil {
 				return err
 			}
-			err = testInvalidReader(t, r)
+			err = testInvalidReader(r)
 			if err != nil {
 				return err
 			}
@@ -295,10 +286,8 @@ func testInvalidReader(t *testing.T, r Reader) error {
 // Execute equivalency and non-equivalency tests, where true for eq means
 // equivalency and false denotes non-equivalency test.
 func testEquivalency(t *testing.T, fp string, eq bool) {
-	file, er := os.Open(fp)
-	if er != nil {
-		t.Fatal(er)
-	}
+	file, err := os.Open(fp)
+	require.NoError(t, err)
 
 	r := NewReader(file)
 	topLevelCounter := 0
@@ -312,11 +301,9 @@ func testEquivalency(t *testing.T, fp string, eq bool) {
 		switch ionType {
 		case StructType, ListType, SexpType:
 			fmt.Printf("Checking values of top level %s #%d ...\n", ionType.String(), topLevelCounter)
+			require.NoError(t, r.StepIn())
+
 			var values [][]ionItem
-			err := r.StepIn()
-			if err != nil {
-				t.Fatal(err)
-			}
 			if embDoc {
 				values = handleEmbeddedDoc(t, r)
 			} else {
@@ -324,21 +311,16 @@ func testEquivalency(t *testing.T, fp string, eq bool) {
 					values = append(values, []ionItem{readCurrentValue(t, r)})
 				}
 			}
+
 			equivalencyAssertion(t, values, eq)
-			err = r.StepOut()
+
+			require.NoError(t, r.StepOut())
+
 			topLevelCounter++
-			if err != nil {
-				t.Fatal(err)
-			}
 		}
 	}
-	if r.Err() != nil {
-		t.Error()
-	}
-	err := file.Close()
-	if err != nil {
-		t.Fatal(err)
-	}
+	assert.NoError(t, r.Err())
+	require.NoError(t, file.Close())
 }
 
 // Handle equivalency tests with embedded_documents annotation
@@ -346,9 +328,8 @@ func handleEmbeddedDoc(t *testing.T, r Reader) [][]ionItem {
 	var values [][]ionItem
 	for r.Next() {
 		str, err := r.StringValue()
-		if err != nil {
-			t.Error("Must be string value.")
-		}
+		assert.NoError(t, err, "Must be string value.")
+
 		if str != nil {
 			newReader := NewReaderString(*str)
 			var ionItems []ionItem
@@ -377,11 +358,11 @@ func equivalencyAssertion(t *testing.T, values [][]ionItem, eq bool) {
 			}
 
 			res, idx := compareIonItemSlices(values[i], values[j])
-			if eq && !res {
-				t.Errorf("Equivalency test failed. All values should be interpreted as "+
+			if eq {
+				assert.True(t, res, "Equivalency test failed. All values should be interpreted as "+
 					"equal for:\nrow %d = %v\nrow %d = %v", i, values[i][idx].value, j, values[j][idx].value)
-			} else if !eq && res {
-				t.Errorf("Non-Equivalency test failed. Values should not be interpreted as "+
+			} else {
+				assert.False(t, res, "Non-Equivalency test failed. Values should not be interpreted as "+
 					"equal for:\nrow %d = %v\nrow %d = %v", i, values[i][idx].value, j, values[j][idx].value)
 			}
 		}
@@ -391,9 +372,7 @@ func equivalencyAssertion(t *testing.T, values [][]ionItem, eq bool) {
 // Read and load the files in testing path and pass them to testing functions.
 func readFilesAndTest(t *testing.T, path string, skipList []string, testingFunc testingFunc) {
 	files, err := ioutil.ReadDir(path)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	for _, file := range files {
 		fp := filepath.Join(path, file.Name())
@@ -411,9 +390,7 @@ func readFilesAndTest(t *testing.T, path string, skipList []string, testingFunc
 
 func loadFile(t *testing.T, path string) []byte {
 	b, err := ioutil.ReadFile(path)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	return b
 }
 
@@ -439,10 +416,7 @@ func writeFromReaderToWriter(t *testing.T, reader Reader, writer Writer) {
 	for reader.Next() {
 		fns, err := reader.FieldName()
 		if err == nil && reader.IsInStruct() && fns != nil {
-			err = writer.FieldNameSymbol(*fns)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, writer.FieldNameSymbol(*fns))
 		}
 
 		an, err := reader.Annotations()
@@ -451,235 +425,141 @@ func writeFromReaderToWriter(t *testing.T, reader Reader, writer Writer) {
 		}
 
 		if len(an) > 0 {
-			err := writer.Annotations(an...)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, writer.Annotations(an...))
 		}
 
 		currentType := reader.Type()
 		if reader.IsNull() {
-			err := writer.WriteNullType(currentType)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, writer.WriteNullType(currentType))
 			continue
 		}
 
 		switch currentType {
 		case NullType:
-			err := writer.WriteNullType(currentType)
-			if err != nil {
-				t.Errorf("Something went wrong while writing a Null value: " + err.Error())
-			}
+			assert.NoError(t, writer.WriteNullType(NullType), "Something went wrong while writing a Null value")
 
 		case BoolType:
 			val, err := reader.BoolValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a Boolean value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a Boolean value")
+
 			if val == nil {
-				err := writer.WriteNullType(BoolType)
-				if err != nil {
-					t.Fatal(err)
-				}
+				assert.NoError(t, writer.WriteNullType(BoolType))
 			} else {
-				err = writer.WriteBool(*val)
-				if err != nil {
-					t.Errorf("Something went wrong while writing a Boolean value: " + err.Error())
-				}
+				assert.NoError(t, writer.WriteBool(*val), "Something went wrong while writing a Boolean value")
 			}
 
 		case IntType:
 			intSize, err := reader.IntSize()
-			if err != nil {
-				t.Errorf("Something went wrong while retrieving the Int size: " + err.Error())
-			}
+			require.NoError(t, err, "Something went wrong while retrieving the Int size")
 
 			switch intSize {
 			case Int32, Int64:
 				val, err := reader.Int64Value()
-				if err != nil {
-					t.Errorf("Something went wrong while reading an Int value: " + err.Error())
-				}
+				assert.NoError(t, err, "Something went wrong while reading an Int value")
+
+				assert.NoError(t, writer.WriteInt(*val), "Something went wrong while writing an Int value")
 
-				err = writer.WriteInt(*val)
-				if err != nil {
-					t.Errorf("Something went wrong while writing an Int value: " + err.Error())
-				}
 			case BigInt:
 				val, err := reader.BigIntValue()
-				if err != nil {
-					t.Errorf("Something went wrong while reading a Big Int value: " + err.Error())
-				}
-				err = writer.WriteBigInt(val)
-				if err != nil {
-					t.Errorf("Something went wrong while writing a Big Int value: " + err.Error())
-				}
+				assert.NoError(t, err, "Something went wrong while reading a Big Int value")
+
+				assert.NoError(t, writer.WriteBigInt(val), "Something went wrong while writing a Big Int value")
+
 			case NullInt:
-				err := writer.WriteNullType(IntType)
-				if err != nil {
-					t.Fatal(err)
-				}
+				assert.NoError(t, writer.WriteNullType(IntType))
+
 			default:
 				t.Error("Expected intSize to be one of Int32, Int64, Uint64, or BigInt")
 			}
 
 		case FloatType:
 			val, err := reader.FloatValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a Float value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a Float value")
+
 			if val == nil {
-				err := writer.WriteNullType(FloatType)
-				if err != nil {
-					t.Fatal(err)
-				}
+				assert.NoError(t, writer.WriteNullType(FloatType))
 			} else {
-				err = writer.WriteFloat(*val)
-				if err != nil {
-					t.Errorf("Something went wrong while writing a Float value: " + err.Error())
-				}
+				assert.NoError(t, writer.WriteFloat(*val), "Something went wrong while writing a Float value")
 			}
 
 		case DecimalType:
 			val, err := reader.DecimalValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a Decimal value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a Decimal value")
+
 			if val == nil {
-				err := writer.WriteNullType(DecimalType)
-				if err != nil {
-					t.Fatal(err)
-				}
+				assert.NoError(t, writer.WriteNullType(DecimalType))
 			} else {
-				err = writer.WriteDecimal(val)
-				if err != nil {
-					t.Errorf("Something went wrong while writing a Decimal value: " + err.Error())
-				}
+				assert.NoError(t, writer.WriteDecimal(val), "Something went wrong while writing a Decimal value")
 			}
 
 		case TimestampType:
 			val, err := reader.TimestampValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a Timestamp value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a Timestamp value")
+
 			if val == nil {
-				err := writer.WriteNullType(FloatType)
-				if err != nil {
-					t.Fatal(err)
-				}
+				assert.NoError(t, writer.WriteNullType(TimestampType))
 			} else {
-				err = writer.WriteTimestamp(*val)
-				if err != nil {
-					t.Errorf("Something went wrong while writing a Timestamp value: " + err.Error())
-				}
+				assert.NoError(t, writer.WriteTimestamp(*val), "Something went wrong while writing a Timestamp value")
 			}
 
 		case SymbolType:
 			val, err := reader.SymbolValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a Symbol value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a Symbol value")
 
-			if val != nil {
-				if val.Text != nil {
-					err = writer.WriteSymbol(*val.Text)
-					if err != nil {
-						t.Errorf("Something went wrong while writing a Symbol value: " + err.Error())
-					}
-				}
+			if val == nil {
+				assert.NoError(t, writer.WriteNullType(SymbolType))
+			} else if val.Text != nil {
+				assert.NoError(t, writer.WriteSymbol(*val.Text), "Something went wrong while writing a Symbol value")
 			}
 
 		case StringType:
 			val, err := reader.StringValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a String value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a String value")
 
-			if val != nil {
-				err = writer.WriteString(*val)
-				if err != nil {
-					t.Errorf("Something went wrong while writing a String value: " + err.Error())
-				}
+			if val == nil {
+				assert.NoError(t, writer.WriteNullType(StringType))
+			} else {
+				assert.NoError(t, writer.WriteString(*val), "Something went wrong while writing a String value")
 			}
 
 		case ClobType:
 			val, err := reader.ByteValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a Clob value: " + err.Error())
-			}
-			err = writer.WriteClob(val)
-			if err != nil {
-				t.Errorf("Something went wrong while writing a Clob value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a Clob value")
+
+			assert.NoError(t, writer.WriteClob(val), "Something went wrong while writing a Clob value")
 
 		case BlobType:
 			val, err := reader.ByteValue()
-			if err != nil {
-				t.Errorf("Something went wrong while reading a Blob value: " + err.Error())
-			}
-			err = writer.WriteBlob(val)
-			if err != nil {
-				t.Errorf("Something went wrong while writing a Blob value: " + err.Error())
-			}
+			assert.NoError(t, err, "Something went wrong while reading a Blob value")
+
+			assert.NoError(t, writer.WriteBlob(val), "Something went wrong while writing a Blob value")
 
 		case SexpType:
-			err := reader.StepIn()
-			if err != nil {
-				t.Fatal(err)
-			}
-			err = writer.BeginSexp()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, reader.StepIn())
+			require.NoError(t, writer.BeginSexp())
+
 			writeFromReaderToWriter(t, reader, writer)
-			err = reader.StepOut()
-			if err != nil {
-				t.Fatal(err)
-			}
-			err = writer.EndSexp()
-			if err != nil {
-				t.Fatal(err)
-			}
+
+			require.NoError(t, reader.StepOut())
+			require.NoError(t, writer.EndSexp())
 
 		case ListType:
-			err := reader.StepIn()
-			if err != nil {
-				t.Fatal(err)
-			}
-			err = writer.BeginList()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, reader.StepIn())
+			require.NoError(t, writer.BeginList())
+
 			writeFromReaderToWriter(t, reader, writer)
-			err = reader.StepOut()
-			if err != nil {
-				t.Fatal(err)
-			}
-			err = writer.EndList()
-			if err != nil {
-				t.Fatal(err)
-			}
+
+			require.NoError(t, reader.StepOut())
+			require.NoError(t, writer.EndList())
 
 		case StructType:
-			err := reader.StepIn()
-			if err != nil {
-				t.Fatal(err)
-			}
-			err = writer.BeginStruct()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, reader.StepIn())
+			require.NoError(t, writer.BeginStruct())
+
 			writeFromReaderToWriter(t, reader, writer)
-			err = reader.StepOut()
-			if err != nil {
-				t.Fatal(err)
-			}
-			err = writer.EndStruct()
-			if err != nil {
-				t.Fatal(err)
-			}
+
+			require.NoError(t, reader.StepOut())
+			require.NoError(t, writer.EndStruct())
 		}
 	}
 }
@@ -689,18 +569,15 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 	var ionItem ionItem
 
 	an, err := reader.Annotations()
-	if err != nil {
-		t.Errorf("Something went wrong when reading annotations. " + err.Error())
-	}
+	require.NoError(t, err, "Something went wrong when reading annotations")
 
 	if len(an) > 0 {
 		ionItem.annotations = an
 	}
 
 	fn, err := reader.FieldName()
-	if err != nil {
-		t.Errorf("Something went wrong when reading field name. " + err.Error())
-	}
+	require.NoError(t, err, "Something went wrong when reading field name")
+
 	if fn != nil {
 		ionItem.fieldName = *fn
 	}
@@ -713,9 +590,8 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 
 	case BoolType:
 		val, err := reader.BoolValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Boolean value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading Boolean value")
+
 		if val == nil {
 			ionItem.value = append(ionItem.value, nil)
 		} else {
@@ -725,9 +601,8 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 
 	case IntType:
 		val, err := reader.BigIntValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Int value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading Int value")
+
 		if val == nil {
 			ionItem.value = append(ionItem.value, nil)
 		} else {
@@ -737,9 +612,8 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 
 	case FloatType:
 		val, err := reader.FloatValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Float value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading Float value")
+
 		if val == nil {
 			ionItem.value = append(ionItem.value, nil)
 		} else {
@@ -749,9 +623,8 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 
 	case DecimalType:
 		val, err := reader.DecimalValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Decimal value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading Decimal value")
+
 		if val == nil {
 			ionItem.value = append(ionItem.value, nil)
 		} else {
@@ -761,9 +634,8 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 
 	case TimestampType:
 		val, err := reader.TimestampValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Timestamp value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading Timestamp value")
+
 		if val == nil {
 			ionItem.value = append(ionItem.value, nil)
 		} else {
@@ -773,17 +645,19 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 
 	case SymbolType:
 		val, err := reader.SymbolValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Symbol value. " + err.Error())
+		assert.NoError(t, err, "Something went wrong when reading Symbol value")
+
+		if val == nil {
+			ionItem.value = append(ionItem.value, nil)
+		} else {
+			ionItem.value = append(ionItem.value, *val)
 		}
-		ionItem.value = append(ionItem.value, val)
 		ionItem.ionType = SymbolType
 
 	case StringType:
 		val, err := reader.StringValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading String value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading String value")
+
 		if val == nil {
 			ionItem.value = append(ionItem.value, nil)
 		} else {
@@ -793,17 +667,15 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 
 	case ClobType:
 		val, err := reader.ByteValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Clob value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading Clob value")
+
 		ionItem.value = append(ionItem.value, val)
 		ionItem.ionType = ClobType
 
 	case BlobType:
 		val, err := reader.ByteValue()
-		if err != nil {
-			t.Errorf("Something went wrong when reading Blob value. " + err.Error())
-		}
+		assert.NoError(t, err, "Something went wrong when reading Blob value")
+
 		ionItem.value = append(ionItem.value, val)
 		ionItem.ionType = BlobType
 
@@ -813,18 +685,14 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 			ionItem.ionType = SexpType
 			break
 		}
-		err := reader.StepIn()
-		if err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, reader.StepIn())
+
 		for reader.Next() {
 			ionItem.value = append(ionItem.value, readCurrentValue(t, reader))
 		}
 		ionItem.ionType = SexpType
-		err = reader.StepOut()
-		if err != nil {
-			t.Fatal(err)
-		}
+
+		require.NoError(t, reader.StepOut())
 
 	case ListType:
 		if reader.IsNull() {
@@ -832,18 +700,14 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 			ionItem.ionType = ListType
 			break
 		}
-		err := reader.StepIn()
-		if err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, reader.StepIn())
+
 		for reader.Next() {
 			ionItem.value = append(ionItem.value, readCurrentValue(t, reader))
 		}
 		ionItem.ionType = ListType
-		err = reader.StepOut()
-		if err != nil {
-			t.Fatal(err)
-		}
+
+		require.NoError(t, reader.StepOut())
 
 	case StructType:
 		if reader.IsNull() {
@@ -851,18 +715,14 @@ func readCurrentValue(t *testing.T, reader Reader) ionItem {
 			ionItem.ionType = StructType
 			break
 		}
-		err := reader.StepIn()
-		if err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, reader.StepIn())
+
 		for reader.Next() {
 			ionItem.value = append(ionItem.value, readCurrentValue(t, reader))
 		}
 		ionItem.ionType = StructType
-		err = reader.StepOut()
-		if err != nil {
-			t.Fatal(err)
-		}
+
+		require.NoError(t, reader.StepOut())
 	}
 
 	return ionItem
diff --git a/ion/marshal_test.go b/ion/marshal_test.go
index be10adc..c07439c 100644
--- a/ion/marshal_test.go
+++ b/ion/marshal_test.go
@@ -21,18 +21,17 @@ import (
 	"strings"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestMarshalText(t *testing.T) {
 	test := func(v interface{}, eval string) {
 		t.Run(eval, func(t *testing.T) {
 			val, err := MarshalText(v)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if string(val) != eval {
-				t.Errorf("expected '%v', got '%v'", eval, string(val))
-			}
+			require.NoError(t, err)
+			assert.Equal(t, eval, string(val))
 		})
 	}
 
@@ -51,7 +50,8 @@ func TestMarshalText(t *testing.T) {
 	test(math.NaN(), "nan")
 
 	test(MustParseDecimal("1.20"), "1.20")
-	test(NewTimestamp(time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC), TimestampPrecisionSecond, TimezoneUTC), "2010-01-01T00:00:00Z")
+	test(NewTimestamp(time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC), TimestampPrecisionSecond, TimezoneUTC),
+		"2010-01-01T00:00:00Z")
 
 	test("hello\tworld", "\"hello\\tworld\"")
 
@@ -86,12 +86,8 @@ func TestMarshalBinary(t *testing.T) {
 	test := func(v interface{}, name string, eval []byte) {
 		t.Run(name, func(t *testing.T) {
 			val, err := MarshalBinary(v)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !bytes.Equal(val, eval) {
-				t.Errorf("expected '%v', got '%v'", fmtbytes(eval), fmtbytes(val))
-			}
+			require.NoError(t, err)
+			assert.True(t, bytes.Equal(val, eval), "expected '%v', got '%v'", fmtbytes(eval), fmtbytes(val))
 		})
 	}
 
@@ -153,12 +149,8 @@ func TestMarshalBinaryLST(t *testing.T) {
 	test := func(v interface{}, name string, lst SymbolTable, eval []byte) {
 		t.Run(name, func(t *testing.T) {
 			val, err := MarshalBinaryLST(v, lst)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !bytes.Equal(val, eval) {
-				t.Errorf("expected '%v', got '%v'", fmtbytes(eval), fmtbytes(val))
-			}
+			require.NoError(t, err)
+			assert.True(t, bytes.Equal(val, eval), "expected '%v', got '%v'", fmtbytes(eval), fmtbytes(val))
 		})
 	}
 
@@ -206,14 +198,10 @@ func TestMarshalNestedStructs(t *testing.T) {
 	}
 
 	val, err := MarshalText(v)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	eval := "{a:1,b:2,c:3,d:4}"
-	if string(val) != eval {
-		t.Errorf("expected %v, got %v", eval, string(val))
-	}
+	assert.Equal(t, eval, string(val))
 }
 
 func TestMarshalHints(t *testing.T) {
@@ -242,9 +230,7 @@ func TestMarshalHints(t *testing.T) {
 	}
 
 	val, err := MarshalText(v)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	eval := `{` +
 		`str:"string",` +
@@ -258,9 +244,7 @@ func TestMarshalHints(t *testing.T) {
 		`sx:(1 2 3)` +
 		`}`
 
-	if string(val) != eval {
-		t.Errorf("expected %v, got %v", eval, string(val))
-	}
+	assert.Equal(t, eval, string(val))
 }
 
 type marshalme uint8
@@ -297,42 +281,27 @@ func TestMarshalCustomMarshaler(t *testing.T) {
 	buf := strings.Builder{}
 	enc := NewTextEncoder(&buf)
 
-	if err := enc.Encode(one); err != nil {
-		t.Fatal(err)
-	}
-	if err := enc.EncodeAs([]marshalme{two, three}, SexpType); err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, enc.Encode(one))
+	require.NoError(t, enc.EncodeAs([]marshalme{two, three}, SexpType))
 
 	v := struct {
 		Num marshalme `ion:"num"`
 	}{four}
-	if err := enc.Encode(v); err != nil {
-		t.Fatal(err)
-	}
-
-	if err := enc.Finish(); err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, enc.Encode(v))
+	require.NoError(t, enc.Finish())
 
 	val := buf.String()
 	eval := "ONE\n(TWO THREE)\n{num:FOUR}\n"
 
-	if val != eval {
-		t.Errorf("expected %v, got %v", eval, val)
-	}
+	assert.Equal(t, eval, val)
 }
 
 func TestMarshalValuesWithAnnotation(t *testing.T) {
 	test := func(v interface{}, testName, eval string) {
 		t.Run(testName, func(t *testing.T) {
 			val, err := MarshalText(v)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if string(val) != eval {
-				t.Errorf("expected '%v', got '%v'", eval, string(val))
-			}
+			require.NoError(t, err)
+			assert.Equal(t, eval, string(val))
 		})
 	}
 
diff --git a/ion/reader_test.go b/ion/reader_test.go
index 1a52797..d6d46d4 100644
--- a/ion/reader_test.go
+++ b/ion/reader_test.go
@@ -21,6 +21,8 @@ import (
 	"path/filepath"
 	"strings"
 	"testing"
+
+	"github.com/stretchr/testify/require"
 )
 
 var blacklist = map[string]bool{
@@ -37,17 +39,13 @@ type drainfunc func(t *testing.T, r Reader, f string)
 
 func TestDecodeFiles(t *testing.T) {
 	testReadDir(t, "../ion-tests/iontestdata/good", func(t *testing.T, r Reader, f string) {
-		// fmt.Println(f)
 		d := NewDecoder(r)
 		for {
 			v, err := d.Decode()
 			if err == ErrNoInput {
 				break
 			}
-			if err != nil {
-				t.Fatal(err)
-			}
-			// fmt.Println(v)
+			require.NoError(t, err)
 			_ = v
 		}
 	})
@@ -55,9 +53,7 @@ func TestDecodeFiles(t *testing.T) {
 
 func testReadDir(t *testing.T, path string, d drainfunc) {
 	files, err := ioutil.ReadDir(path)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	for _, file := range files {
 		fp := filepath.Join(path, file.Name())
@@ -79,15 +75,12 @@ func testReadFile(t *testing.T, path string, d drainfunc) {
 		return
 	}
 
-	//fmt.Printf("**** PATH = %s\n", path)
-
 	file, err := os.Open(path)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer file.Close()
+	require.NoError(t, err)
 
 	r := NewReader(file)
 
 	d(t, r, path)
+
+	require.NoError(t, file.Close())
 }
diff --git a/ion/readerlocalsymboltable_test.go b/ion/readlocalsymboltable_test.go
similarity index 76%
rename from ion/readerlocalsymboltable_test.go
rename to ion/readlocalsymboltable_test.go
index 8c983f8..a6e514f 100644
--- a/ion/readerlocalsymboltable_test.go
+++ b/ion/readlocalsymboltable_test.go
@@ -2,6 +2,8 @@ package ion
 
 import (
 	"testing"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestLocalSymbolTableAppend(t *testing.T) {
@@ -17,7 +19,7 @@ func TestLocalSymbolTableAppend(t *testing.T) {
 			null`
 
 	r := NewReaderString(text)
-	r.Next()
+	assert.True(t, r.Next())
 	st := r.SymbolTable()
 
 	imports := st.Imports()
@@ -56,7 +58,7 @@ func TestLocalSymbolTableMultiAppend(t *testing.T) {
 			null`
 
 	r := NewReaderString(text)
-	r.Next()
+	assert.True(t, r.Next())
 	st := r.SymbolTable()
 
 	imports := st.Imports()
@@ -89,19 +91,18 @@ func TestLocalSymbolTableAppendEmptyList(t *testing.T) {
 		null`
 
 	r := NewReaderString(original + "null")
-	r.Next()
+	assert.True(t, r.Next())
 	ost := r.SymbolTable()
 
 	originalSymbol := ost.Find("s1")
 
 	r = NewReaderString(appended)
-	r.Next()
+	assert.True(t, r.Next())
 	ast := r.SymbolTable()
 	appendedSymbol := ast.Find("s1")
 
-	if originalSymbol.LocalSID != appendedSymbol.LocalSID {
-		t.Errorf("Original symbol SID: %v,did not match Appended symbol SID: %v", originalSymbol.LocalSID, appendedSymbol.LocalSID)
-	}
+	assert.Equal(t, originalSymbol.LocalSID, appendedSymbol.LocalSID,
+		"Original symbol SID: %v,did not match Appended symbol SID: %v", originalSymbol.LocalSID, appendedSymbol.LocalSID)
 }
 
 func TestLocalSymbolTableAppendNonUnique(t *testing.T) {
@@ -119,8 +120,8 @@ func TestLocalSymbolTableAppendNonUnique(t *testing.T) {
 			$12`
 
 	r := NewReaderString(text)
-	r.Next()
-	r.Next()
+	assert.True(t, r.Next())
+	assert.True(t, r.Next())
 	st := r.SymbolTable()
 	systemMaxID := getSystemMaxID(st)
 
@@ -144,8 +145,8 @@ func TestLocalSymbolTableAppendOutOfBounds(t *testing.T) {
 			$12`
 
 	r := NewReaderString(text)
-	r.Next()
-	r.Next()
+	assert.True(t, r.Next())
+	assert.True(t, r.Next())
 	st := r.SymbolTable()
 	systemMaxID := getSystemMaxID(st)
 
@@ -162,28 +163,18 @@ func getSystemMaxID(st SymbolTable) uint64 {
 
 func checkSymbol(t *testing.T, eval string, SID uint64, st SymbolTable) {
 	val, ok := st.FindByID(SID)
-	if !ok {
-		t.Errorf("Failed on checking symbol. Symbol table could not find symbol given the ID: %v", SID)
-	}
-	if val != eval {
-		t.Errorf("Failed on checking symbol. Symbol table returned the symbol name: %v, did not match the expected name: %v", val, eval)
-	}
+	assert.True(t, ok, "Failed on checking symbol. Symbol table could not find symbol given the ID: %v", SID)
+	assert.Equal(t, eval, val, "Failed on checking symbol. Symbol table returned the symbol name: %v, did not match the expected name: %v", val, eval)
 }
 
 func checkUnknownSymbolText(t *testing.T, val string, st SymbolTable) {
 	symbolToken := st.Find(val)
-	if symbolToken != nil {
-		t.Errorf("Failed on checking unknown symbol. Symbol table found symbol given the name: %v", val)
-	}
+	assert.Nil(t, symbolToken, "Failed on checking unknown symbol. Symbol table found symbol given the name: %v", val)
 	_, ok := st.FindByName(val)
-	if ok {
-		t.Errorf("Failed on checking unknown symbol. Symbol table found symbol given the name: %v", val)
-	}
+	assert.False(t, ok, "Failed on checking unknown symbol. Symbol table found symbol given the name: %v", val)
 }
 
 func checkUnknownSymbolID(t *testing.T, val uint64, st SymbolTable) {
 	_, ok := st.FindByID(val)
-	if ok {
-		t.Errorf("Failed on checking unknown symbol. Symbol table found symbol given the SID: %v", val)
-	}
+	assert.False(t, ok, "Failed on checking unknown symbol. Symbol table found symbol given the SID: %v", val)
 }
diff --git a/ion/skipper_test.go b/ion/skipper_test.go
index 1579f9e..0f15718 100644
--- a/ion/skipper_test.go
+++ b/ion/skipper_test.go
@@ -17,6 +17,9 @@ package ion
 
 import (
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestSkipNumber(t *testing.T) {
@@ -172,21 +175,16 @@ func testSkip(t *testing.T, f skipFunc) (skipTestFunc, skipTestErrFunc) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
 			c, err := f(tok)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if c != ec {
-				t.Errorf("expected '%c', got '%c'", ec, c)
-			}
+			require.NoError(t, err)
+			assert.Equal(t, ec, c)
 		})
 	}
 	testErr := func(str string, e string) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
 			_, err := f(tok)
-			if err == nil || err.Error() != e {
-				t.Errorf("expected err=%v, got err=%v", e, err)
-			}
+			require.Error(t, err)
+			assert.Equal(t, e, err.Error())
 		})
 	}
 	return test, testErr
diff --git a/ion/symboltable_test.go b/ion/symboltable_test.go
index 5d25454..baeb45f 100644
--- a/ion/symboltable_test.go
+++ b/ion/symboltable_test.go
@@ -18,6 +18,9 @@ package ion
 import (
 	"fmt"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestSharedSymbolTable(t *testing.T) {
@@ -30,15 +33,9 @@ func TestSharedSymbolTable(t *testing.T) {
 		"ghi",
 	})
 
-	if st.Name() != "test" {
-		t.Errorf("wrong name: %v", st.Name())
-	}
-	if st.Version() != 2 {
-		t.Errorf("wrong version: %v", st.Version())
-	}
-	if st.MaxID() != 6 {
-		t.Errorf("wrong maxid: %v", st.MaxID())
-	}
+	assert.Equal(t, "test", st.Name())
+	assert.Equal(t, 2, st.Version())
+	assert.Equal(t, 6, int(st.MaxID()))
 
 	testFindByName(t, st, "def", 2)
 	testFindByName(t, st, "null", 4)
@@ -58,9 +55,7 @@ func TestSharedSymbolTable(t *testing.T) {
 func TestLocalSymbolTable(t *testing.T) {
 	st := NewLocalSymbolTable(nil, []string{"foo", "bar"})
 
-	if st.MaxID() != 11 {
-		t.Errorf("wrong maxid: %v", st.MaxID())
-	}
+	assert.Equal(t, 11, int(st.MaxID()))
 
 	testFindByName(t, st, "$ion", 1)
 	testFindByName(t, st, "foo", 10)
@@ -92,9 +87,7 @@ func TestLocalSymbolTableWithImports(t *testing.T) {
 		"bar2",
 	})
 
-	if st.MaxID() != 13 { // 9 from $ion.1, 2 from test.1, 2 local.
-		t.Errorf("wrong maxid: %v", st.MaxID())
-	}
+	assert.Equal(t, 13, int(st.MaxID()))
 
 	testFindByName(t, st, "$ion", 1)
 	testFindByName(t, st, "$ion_shared_symbol_table", 9)
@@ -125,33 +118,19 @@ func TestSymbolTableBuilder(t *testing.T) {
 	b := NewSymbolTableBuilder()
 
 	id, ok := b.Add("name")
-	if ok {
-		t.Error("Add(name) returned true")
-	}
-	if id != 4 {
-		t.Errorf("Add(name) returned %v", id)
-	}
+	assert.False(t, ok, "Add(name) returned true")
+	assert.Equal(t, 4, int(id), "Add(name) returned %v", id)
 
 	id, ok = b.Add("foo")
-	if !ok {
-		t.Error("Add(foo) returned false")
-	}
-	if id != 10 {
-		t.Errorf("Add(foo) returned %v", id)
-	}
+	assert.True(t, ok, "Add(foo) returned false")
+	assert.Equal(t, 10, int(id), "Add(foo) returned %v", id)
 
 	id, ok = b.Add("foo")
-	if ok {
-		t.Error("Second Add(foo) returned true")
-	}
-	if id != 10 {
-		t.Errorf("Second Add(foo) returned %v", id)
-	}
+	assert.False(t, ok, "Second Add(foo) returned true")
+	assert.Equal(t, 10, int(id), "Second Add(foo) returned %v", id)
 
 	st := b.Build()
-	if st.MaxID() != 10 {
-		t.Errorf("maxid returned %v", st.MaxID())
-	}
+	assert.Equal(t, 10, int(st.MaxID()), "maxid returned %v", st.MaxID())
 
 	testFindByName(t, st, "$ion", 1)
 	testFindByName(t, st, "foo", 10)
@@ -166,16 +145,10 @@ func testFindByName(t *testing.T, st SymbolTable, sym string, expected uint64) {
 	t.Run("FindByName("+sym+")", func(t *testing.T) {
 		actual, ok := st.FindByName(sym)
 		if expected == 0 {
-			if ok {
-				t.Fatalf("unexpectedly found: %v", actual)
-			}
+			require.False(t, ok)
 		} else {
-			if !ok {
-				t.Fatal("unexpectedly not found")
-			}
-			if actual != expected {
-				t.Errorf("expected %v, got %v", expected, actual)
-			}
+			require.True(t, ok)
+			assert.Equal(t, expected, actual)
 		}
 	})
 }
@@ -184,16 +157,10 @@ func testFindByID(t *testing.T, st SymbolTable, id uint64, expected string) {
 	t.Run(fmt.Sprintf("FindByID(%v)", id), func(t *testing.T) {
 		actual, ok := st.FindByID(id)
 		if expected == "" {
-			if ok {
-				t.Fatalf("unexpectedly found: %v", actual)
-			}
+			require.False(t, ok)
 		} else {
-			if !ok {
-				t.Fatal("unexpectedly not found")
-			}
-			if actual != expected {
-				t.Errorf("expected %v, got %v", expected, actual)
-			}
+			require.True(t, ok)
+			assert.Equal(t, expected, actual)
 		}
 	})
 }
@@ -201,23 +168,16 @@ func testFindByID(t *testing.T, st SymbolTable, id uint64, expected string) {
 func testFindSymbolToken(t *testing.T, st SymbolTable, sym string, expected SymbolToken) {
 	t.Run("Find("+sym+")", func(t *testing.T) {
 		actual := st.Find(sym)
+		require.NotNil(t, actual)
 
-		if actual == nil {
-			t.Fatal("unexpectedly not found")
-		}
-
-		if !actual.Equal(&expected) {
-			t.Errorf("expected %v, got %v", expected, actual)
-		}
+		assert.True(t, actual.Equal(&expected), "expected %v, got %v", expected, actual)
 	})
 }
 
 func testString(t *testing.T, st SymbolTable, expected string) {
 	t.Run("String()", func(t *testing.T) {
 		actual := st.String()
-		if actual != expected {
-			t.Errorf("expected %v, got %v", expected, actual)
-		}
+		assert.Equal(t, expected, actual)
 	})
 }
 
diff --git a/ion/symboltoken_test.go b/ion/symboltoken_test.go
index b3941bc..a35181a 100644
--- a/ion/symboltoken_test.go
+++ b/ion/symboltoken_test.go
@@ -20,6 +20,7 @@ import (
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
+	"github.com/stretchr/testify/assert"
 )
 
 var symbolTokenEqualsTestData = []struct {
@@ -48,13 +49,9 @@ func TestSymbolTokenEqualsOperator(t *testing.T) {
 		st2 := SymbolToken{Text: testData.text2, LocalSID: testData.sid2, Source: testData.source2}
 
 		if testData.equals {
-			if !st1.Equal(&st2) {
-				t.Errorf("expected %v, got %v", true, false)
-			}
+			assert.True(t, st1.Equal(&st2))
 		} else {
-			if st1.Equal(&st2) {
-				t.Errorf("expected %v, got %v", true, false)
-			}
+			assert.False(t, st1.Equal(&st2))
 		}
 	}
 }
@@ -99,21 +96,16 @@ func TestSymbolToken_String(t *testing.T) {
 
 	for _, c := range cases {
 		t.Run(c.desc, func(t *testing.T) {
-			if diff := cmp.Diff(c.expected, c.token.String()); diff != "" {
-				t.Errorf("Token String() differs (-expected, +actual):\n%s", diff)
-			}
+			diff := cmp.Diff(c.expected, c.token.String())
+			assert.Empty(t, diff, "Token String() differs (-expected, +actual):\n%s", diff)
 		})
 	}
 }
 
 func TestNewImportSource(t *testing.T) {
 	is := newSource("table", 1)
-	if is.Table != "table" {
-		t.Errorf("expected %v, got %v", "table", is.Table)
-	}
-	if is.SID != 1 {
-		t.Errorf("expected %v, got %v", 1, is.SID)
-	}
+	assert.Equal(t, "table", is.Table)
+	assert.Equal(t, int64(1), is.SID)
 }
 
 var importSourceEqualsTestData = []struct {
@@ -135,13 +127,9 @@ func TestImportSourceEqualsOperator(t *testing.T) {
 		is2 := newSource(testData.text2, testData.sid2)
 
 		if testData.equals {
-			if !is1.Equal(is2) {
-				t.Errorf("expected %v, got %v", true, false)
-			}
+			assert.True(t, is1.Equal(is2))
 		} else {
-			if is1.Equal(is2) {
-				t.Errorf("expected %v, got %v", false, true)
-			}
+			assert.False(t, is1.Equal(is2))
 		}
 	}
 }
@@ -150,26 +138,18 @@ func TestNewSymbolTokenThatAlreadyExistInSymbolTable(t *testing.T) {
 	expectedSymbolToken := SymbolToken{Text: newString("$ion"), LocalSID: SymbolIDUnknown}
 
 	actualSymbolToken, err := NewSymbolToken(V1SystemSymbolTable, "$ion")
-	if err != nil {
-		t.Errorf("expected NewSymbolToken() to execute without errors; %s", err.Error())
-	}
+	assert.NoError(t, err, "expected NewSymbolToken() to execute without errors")
 
-	if !actualSymbolToken.Equal(&expectedSymbolToken) {
-		t.Errorf("expected %v, got %v", expectedSymbolToken, actualSymbolToken)
-	}
+	assert.True(t, actualSymbolToken.Equal(&expectedSymbolToken), "expected %v, got %v", expectedSymbolToken, actualSymbolToken)
 }
 
 func TestNewSymbolTokenThatDoesNotExistInSymbolTable(t *testing.T) {
 	expectedSymbolToken := SymbolToken{Text: newString("newToken"), LocalSID: SymbolIDUnknown}
 
 	actualSymbolToken, err := NewSymbolToken(V1SystemSymbolTable, "newToken")
-	if err != nil {
-		t.Errorf("expected NewSymbolToken() to execute without errors; %s", err.Error())
-	}
+	assert.NoError(t, err, "expected NewSymbolToken() to execute without errors")
 
-	if !actualSymbolToken.Equal(&expectedSymbolToken) {
-		t.Errorf("expected %v, got %v", expectedSymbolToken, actualSymbolToken)
-	}
+	assert.True(t, actualSymbolToken.Equal(&expectedSymbolToken), "expected %v, got %v", expectedSymbolToken, actualSymbolToken)
 }
 
 func TestNewSymbolTokensThatAlreadyExistInSymbolTable(t *testing.T) {
@@ -178,14 +158,10 @@ func TestNewSymbolTokensThatAlreadyExistInSymbolTable(t *testing.T) {
 		{Text: newString("$ion_1_0"), LocalSID: SymbolIDUnknown}}
 
 	actualSymbolTokens, err := NewSymbolTokens(V1SystemSymbolTable, []string{"$ion", "$ion_1_0"})
-	if err != nil {
-		t.Errorf("expected NewSymbolTokens() to execute without errors; %s", err.Error())
-	}
+	assert.NoError(t, err, "expected NewSymbolTokens() to execute without errors")
 
 	for index, actualSymbolToken := range actualSymbolTokens {
-		if !actualSymbolToken.Equal(&expectedSymbolTokens[index]) {
-			t.Errorf("expected %v, got %v", &expectedSymbolTokens[index], actualSymbolToken)
-		}
+		assert.True(t, actualSymbolToken.Equal(&expectedSymbolTokens[index]), "expected %v, got %v", &expectedSymbolTokens[index], actualSymbolToken)
 	}
 }
 
@@ -195,14 +171,10 @@ func TestNewSymbolTokensThatDoNotExistInSymbolTable(t *testing.T) {
 		{Text: newString("newToken2"), LocalSID: SymbolIDUnknown}}
 
 	actualSymbolTokens, err := NewSymbolTokens(V1SystemSymbolTable, []string{"newToken1", "newToken2"})
-	if err != nil {
-		t.Errorf("expected NewSymbolTokens() to execute without errors; %s", err.Error())
-	}
+	assert.NoError(t, err, "expected NewSymbolTokens() to execute without errors")
 
 	for index, actualSymbolToken := range actualSymbolTokens {
-		if !actualSymbolToken.Equal(&expectedSymbolTokens[index]) {
-			t.Errorf("expected %v, got %v", &expectedSymbolTokens[index], actualSymbolToken)
-		}
+		assert.True(t, actualSymbolToken.Equal(&expectedSymbolTokens[index]), "expected %v, got %v", &expectedSymbolTokens[index], actualSymbolToken)
 	}
 }
 
@@ -210,13 +182,10 @@ func TestSymbolIdentifier(t *testing.T) {
 	test := func(sym string, expectedSID int64, expectedOK bool) {
 		t.Run(sym, func(t *testing.T) {
 			sid, ok := symbolIdentifier(sym)
+			assert.Equal(t, expectedOK, ok)
 
-			if ok != expectedOK {
-				t.Errorf("expected %v, got %v", expectedOK, ok)
-			}
-
-			if expectedOK && sid != expectedSID {
-				t.Errorf("expected %v, got %v", expectedSID, sid)
+			if expectedOK {
+				assert.Equal(t, expectedSID, sid)
 			}
 		})
 	}
diff --git a/ion/textreader_test.go b/ion/textreader_test.go
index d13cae6..e49f4b3 100644
--- a/ion/textreader_test.go
+++ b/ion/textreader_test.go
@@ -21,6 +21,9 @@ import (
 	"math/big"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestReadTextSymbols(t *testing.T) {
@@ -67,8 +70,8 @@ func TestReadTextAnnotations(t *testing.T) {
 				]`
 
 	r := NewReaderString(ionText)
-	r.Next()
-	r.StepIn()
+	assert.True(t, r.Next())
+	assert.NoError(t, r.StepIn())
 
 	_nextA(t, r, []SymbolToken{SymbolToken{Text: nil, LocalSID: 0}}, false, false)
 	_nextA(t, r, []SymbolToken{SymbolToken{Text: newString("$4"), LocalSID: SymbolIDUnknown}}, false, false)
@@ -98,11 +101,9 @@ func TestReadTextFieldNames(t *testing.T) {
 				}`
 
 	r := NewReaderString(ionText)
-	r.Next()
-	err := r.StepIn()
-	if err != nil {
-		t.Errorf("stepIn returned err: %v", err.Error())
-	}
+	assert.True(t, r.Next())
+	assert.NoError(t, r.StepIn())
+
 	_nextF(t, r, &SymbolToken{Text: nil, LocalSID: 0}, false, false)
 	_nextF(t, r, &SymbolToken{Text: newString("$4"), LocalSID: SymbolIDUnknown}, false, false)
 	_nextF(t, r, &SymbolToken{Text: newString("name"), LocalSID: 4}, false, false)
@@ -119,11 +120,8 @@ func TestReadTextNullFieldName(t *testing.T) {
 				}`
 
 	r := NewReaderString(ionText)
-	r.Next()
-	err := r.StepIn()
-	if err != nil {
-		t.Errorf("stepIn returned err: %v", err.Error())
-	}
+	assert.True(t, r.Next())
+	assert.NoError(t, r.StepIn())
 	_nextF(t, r, &SymbolToken{}, true, true)
 }
 
@@ -148,12 +146,8 @@ func TestReadSexps(t *testing.T) {
 	}
 
 	test("(\t)", func(t *testing.T, r Reader) {
-		if r.Next() {
-			t.Errorf("next returned true")
-		}
-		if r.Err() != nil {
-			t.Fatal(r.Err())
-		}
+		assert.False(t, r.Next())
+		require.NoError(t, r.Err())
 	})
 
 	test("(foo)", func(t *testing.T, r Reader) {
@@ -268,12 +262,9 @@ func TestClobs(t *testing.T) {
 			_next(t, r, ClobType)
 
 			val, err := r.ByteValue()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !bytes.Equal(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			require.NoError(t, err)
+
+			assert.True(t, bytes.Equal(val, eval), "expected %v, got %v", eval, val)
 
 			_eof(t, r)
 		})
@@ -292,12 +283,9 @@ func TestBlobs(t *testing.T) {
 			_next(t, r, BlobType)
 
 			val, err := r.ByteValue()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !bytes.Equal(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			require.NoError(t, err)
+
+			assert.True(t, bytes.Equal(val, eval), "expected %v, got %v", eval, val)
 
 			_eof(t, r)
 		})
@@ -315,13 +303,9 @@ func TestTimestamps(t *testing.T) {
 			_nextAF(t, r, TimestampType, nil, etas)
 
 			val, err := r.TimestampValue()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
-			if !val.Equal(eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, val.Equal(eval), "expected %v, got %v", eval, val)
 
 			_eof(t, r)
 		})
@@ -358,12 +342,9 @@ func TestDecimals(t *testing.T) {
 			_nextAF(t, r, DecimalType, nil, etas)
 
 			val, err := r.DecimalValue()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !ee.Equal(val) {
-				t.Errorf("expected %v, got %v", ee, val)
-			}
+			require.NoError(t, err)
+
+			assert.True(t, ee.Equal(val), "expected %v, got %v", ee, val)
 
 			_eof(t, r)
 		})
@@ -418,20 +399,14 @@ func TestInts(t *testing.T) {
 	}
 
 	test("null.int", func(t *testing.T, r Reader) {
-		if !r.IsNull() {
-			t.Fatal("expected isnull=true, got false")
-		}
+		require.True(t, r.IsNull())
 	})
 
 	testInt := func(str string, eval int) {
 		test(str, func(t *testing.T, r Reader) {
 			val, err := r.IntValue()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if *val != eval {
-				t.Errorf("expected %v, got %v", eval, *val)
-			}
+			require.NoError(t, err)
+			assert.Equal(t, eval, *val)
 		})
 	}
 
@@ -446,12 +421,8 @@ func TestInts(t *testing.T) {
 	testInt64 := func(str string, eval int64) {
 		test(str, func(t *testing.T, r Reader) {
 			val, err := r.Int64Value()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if *val != eval {
-				t.Errorf("expected %v, got %v", eval, *val)
-			}
+			require.NoError(t, err)
+			assert.Equal(t, eval, *val)
 		})
 	}
 
@@ -461,14 +432,10 @@ func TestInts(t *testing.T) {
 	testBigInt := func(str string, estr string) {
 		test(str, func(t *testing.T, r Reader) {
 			val, err := r.BigIntValue()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
 			eval, _ := (&big.Int{}).SetString(estr, 0)
-			if eval.Cmp(val) != 0 {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, eval.Cmp(val) == 0, "expected %v, got %v", eval, val)
 		})
 	}
 
@@ -532,53 +499,36 @@ func TestTopLevelOperators(t *testing.T) {
 
 	_symbol(t, r, SymbolToken{Text: newString("a"), LocalSID: SymbolIDUnknown})
 
-	if r.Next() {
-		t.Errorf("next returned true")
-	}
-	if r.Err() == nil {
-		t.Error("no error")
-	}
+	assert.False(t, r.Next())
+	assert.Error(t, r.Err())
 }
 
 func TestTrsToString(t *testing.T) {
 	for i := trsDone; i <= trsAfterValue+1; i++ {
-		str := i.String()
-		if str == "" {
-			t.Errorf("expected a non-empty string for trs %v", uint8(i))
-		}
+		assert.NotEmpty(t, i.String(), "expected a non-empty string for trs %v", uint8(i))
 	}
 }
 
 func TestInStruct(t *testing.T) {
 	r := NewReaderString("[ { a:() } ]")
 
-	r.Next()
-	r.StepIn() // In the list, before the struct
-	if r.IsInStruct() {
-		t.Fatal("IsInStruct returned true before we were in a struct")
-	}
+	assert.True(t, r.Next())
+	assert.NoError(t, r.StepIn()) // In the list, before the struct
+	require.False(t, r.IsInStruct(), "IsInStruct returned true before we were in a struct")
 
-	r.Next()
-	r.StepIn() // In the struct
-	if !r.IsInStruct() {
-		t.Fatal("We were in a struct, IsInStruct should have returned true")
-	}
+	assert.True(t, r.Next())
+	assert.NoError(t, r.StepIn()) // In the struct
+	require.True(t, r.IsInStruct(), "We were in a struct, IsInStruct should have returned true")
 
-	r.Next()
-	r.StepIn() // In the Sexp
-	if r.IsInStruct() {
-		t.Fatal("IsInStruct returned true before we were in a struct")
-	}
+	assert.True(t, r.Next())
+	assert.NoError(t, r.StepIn()) // In the Sexp
+	require.False(t, r.IsInStruct(), "IsInStruct returned true before we were in a struct")
 
-	r.StepOut() // Out of the Sexp, back in the struct again
-	if !r.IsInStruct() {
-		t.Fatal("We were in a struct, IsInStruct should have returned true")
-	}
+	assert.NoError(t, r.StepOut()) // Out of the Sexp, back in the struct again
+	require.True(t, r.IsInStruct(), "We were in a struct, IsInStruct should have returned true")
 
-	r.StepOut() // out of struct, back in the list again
-	if r.IsInStruct() {
-		t.Fatal("IsInStruct returned true before we were in a struct")
-	}
+	assert.NoError(t, r.StepOut()) // out of struct, back in the list again
+	require.False(t, r.IsInStruct(), "IsInStruct returned true before we were in a struct")
 }
 
 type containerhandler func(t *testing.T, r Reader)
@@ -609,19 +559,13 @@ func _listAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, f con
 
 func _containerAF(t *testing.T, r Reader, et Type, efn *SymbolToken, etas []SymbolToken, f containerhandler) {
 	_nextAF(t, r, et, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.%v", et, et)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.%v", et, et)
 
-	if err := r.StepIn(); err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, r.StepIn())
 
 	f(t, r)
 
-	if err := r.StepOut(); err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, r.StepOut())
 }
 
 func _int(t *testing.T, r Reader, eval int) {
@@ -630,25 +574,15 @@ func _int(t *testing.T, r Reader, eval int) {
 
 func _intAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval int) {
 	_nextAF(t, r, IntType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.int", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.int", eval)
 
 	size, err := r.IntSize()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if size != Int32 {
-		t.Errorf("expected size=Int32, got %v", size)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, Int32, size)
 
 	val, err := r.IntValue()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if *val != eval {
-		t.Errorf("expected %v, got %v", eval, *val)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, eval, *val)
 }
 
 func _int64(t *testing.T, r Reader, eval int64) {
@@ -657,25 +591,15 @@ func _int64(t *testing.T, r Reader, eval int64) {
 
 func _int64AF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval int64) {
 	_nextAF(t, r, IntType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.int", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.int", eval)
 
 	size, err := r.IntSize()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if size != Int64 {
-		t.Errorf("expected size=Int64, got %v", size)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, Int64, size)
 
 	val, err := r.Int64Value()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if *val != eval {
-		t.Errorf("expected %v, got %v", eval, *val)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, eval, *val)
 }
 
 func _bigInt(t *testing.T, r Reader, eval *big.Int) {
@@ -684,25 +608,15 @@ func _bigInt(t *testing.T, r Reader, eval *big.Int) {
 
 func _bigIntAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval *big.Int) {
 	_nextAF(t, r, IntType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.int", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.int", eval)
 
 	size, err := r.IntSize()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if size != BigInt {
-		t.Errorf("expected size=BigInt, got %v", size)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, BigInt, size)
 
 	val, err := r.BigIntValue()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if val.Cmp(eval) != 0 {
-		t.Errorf("expected %v, got %v", eval, val)
-	}
+	require.NoError(t, err)
+	assert.True(t, val.Cmp(eval) == 0, "expected %v, got %v", eval, val)
 }
 
 func _float(t *testing.T, r Reader, eval float64) {
@@ -711,21 +625,15 @@ func _float(t *testing.T, r Reader, eval float64) {
 
 func _floatAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval float64) {
 	_nextAF(t, r, FloatType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.float", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.float", eval)
 
 	val, err := r.FloatValue()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	if math.IsNaN(eval) {
-		if !math.IsNaN(*val) {
-			t.Errorf("expected %v, got %v", eval, *val)
-		}
-	} else if eval != *val {
-		t.Errorf("expected %v, got %v", eval, *val)
+		assert.True(t, math.IsNaN(*val), "expected %v, got %v", eval, val)
+	} else {
+		assert.Equal(t, eval, *val)
 	}
 }
 
@@ -735,18 +643,12 @@ func _decimal(t *testing.T, r Reader, eval *Decimal) {
 
 func _decimalAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval *Decimal) {
 	_nextAF(t, r, DecimalType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.decimal", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.decimal", eval)
 
 	val, err := r.DecimalValue()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
-	if !eval.Equal(val) {
-		t.Errorf("expected %v, got %v", eval, val)
-	}
+	assert.True(t, eval.Equal(val), "expected %v, got %v", eval, val)
 }
 
 func _timestamp(t *testing.T, r Reader, eval Timestamp) {
@@ -755,18 +657,12 @@ func _timestamp(t *testing.T, r Reader, eval Timestamp) {
 
 func _timestampAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval Timestamp) {
 	_nextAF(t, r, TimestampType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.timestamp", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.timestamp", eval)
 
 	val, err := r.TimestampValue()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
-	if !eval.Equal(*val) {
-		t.Errorf("expected %v, got %v", eval, *val)
-	}
+	assert.True(t, eval.Equal(*val), "expected %v, got %v", eval, val)
 }
 
 func _string(t *testing.T, r Reader, eval *string) {
@@ -775,20 +671,15 @@ func _string(t *testing.T, r Reader, eval *string) {
 
 func _stringAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval *string) {
 	_nextAF(t, r, StringType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.string", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.string", eval)
 
 	val, err := r.StringValue()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	if eval == nil {
-		if val != eval {
-			t.Errorf("expected %v, got %v", eval, val)
-		}
-	} else if *val != *eval {
-		t.Errorf("expected %v, got %v", *eval, *val)
+		assert.Equal(t, eval, val)
+	} else {
+		assert.Equal(t, *eval, *val)
 	}
 }
 
@@ -807,27 +698,19 @@ func _symbolAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eva
 	}
 
 	if evalSt != nil {
-		if r.IsNull() {
-			t.Fatalf("expected %v, got null.symbol", evalSt.Text)
-		}
+		require.False(t, r.IsNull())
 	}
+
 	symbolVal, err := r.SymbolValue()
 	if isSymbolValueError {
-		if err == nil {
-			t.Fatal("symboltoken did not return an error")
-		}
+		require.Error(t, err)
 	} else {
-		if err != nil {
-			t.Fatal(err)
-		}
-		if evalSt != nil {
-			if !symbolVal.Equal(evalSt) {
-				t.Errorf("expected %v, got %v", &evalSt, symbolVal)
-			}
+		require.NoError(t, err)
+
+		if evalSt == nil {
+			assert.True(t, symbolVal == nil, "expected %v, got %v", &evalSt, symbolVal)
 		} else {
-			if symbolVal != nil {
-				t.Errorf("expected %v, got %v", evalSt, symbolVal)
-			}
+			assert.True(t, symbolVal.Equal(evalSt), "expected %v, got %v", &evalSt, symbolVal)
 		}
 	}
 }
@@ -838,17 +721,11 @@ func _bool(t *testing.T, r Reader, eval bool) {
 
 func _boolAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval bool) {
 	_nextAF(t, r, BoolType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.bool", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.bool", eval)
 
 	val, err := r.BoolValue()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if *val != eval {
-		t.Errorf("expected %v, got %v", eval, *val)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, eval, *val, "expected %v, got %v", eval, val)
 }
 
 func _clob(t *testing.T, r Reader, eval []byte) {
@@ -857,17 +734,11 @@ func _clob(t *testing.T, r Reader, eval []byte) {
 
 func _clobAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval []byte) {
 	_nextAF(t, r, ClobType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.clob", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.clob", eval)
 
 	val, err := r.ByteValue()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(val, eval) {
-		t.Errorf("expected %v, got %v", eval, val)
-	}
+	require.NoError(t, err)
+	assert.True(t, bytes.Equal(val, eval), "expected %v, got %v", eval, val)
 }
 
 func _blob(t *testing.T, r Reader, eval []byte) {
@@ -876,17 +747,11 @@ func _blob(t *testing.T, r Reader, eval []byte) {
 
 func _blobAF(t *testing.T, r Reader, efn *SymbolToken, etas []SymbolToken, eval []byte) {
 	_nextAF(t, r, BlobType, efn, etas)
-	if r.IsNull() {
-		t.Fatalf("expected %v, got null.blob", eval)
-	}
+	require.False(t, r.IsNull(), "expected %v, got null.blob", eval)
 
 	val, err := r.ByteValue()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(val, eval) {
-		t.Errorf("expected %v, got %v", eval, val)
-	}
+	require.NoError(t, err)
+	assert.True(t, bytes.Equal(val, eval), "expected %v, got %v", eval, val)
 }
 
 func _null(t *testing.T, r Reader, et Type) {
@@ -895,9 +760,7 @@ func _null(t *testing.T, r Reader, et Type) {
 
 func _nullAF(t *testing.T, r Reader, et Type, efn *SymbolToken, etas []SymbolToken) {
 	_nextAF(t, r, et, efn, etas)
-	if !r.IsNull() {
-		t.Error("isnull returned false")
-	}
+	assert.True(t, r.IsNull())
 }
 
 func _next(t *testing.T, r Reader, et Type) {
@@ -905,31 +768,20 @@ func _next(t *testing.T, r Reader, et Type) {
 }
 
 func _nextAF(t *testing.T, r Reader, et Type, efn *SymbolToken, etas []SymbolToken) {
-	if !r.Next() {
-		t.Fatal(r.Err())
-	}
-	if r.Type() != et {
-		t.Fatalf("expected %v, got %v", et, r.Type())
-	}
+	require.True(t, r.Next(), "r.Next() failed with error: %v", r.Err())
+	require.Equal(t, et, r.Type())
 
 	fn, err := r.FieldName()
-	if err != nil {
-		t.Errorf("fieldname returned error: %v", err.Error())
-	}
+	assert.NoError(t, err)
 
-	if efn != nil && fn != nil && !efn.Equal(fn) {
-		t.Errorf("expected fieldname=%v, got %v", *efn, *fn)
+	if efn != nil && fn != nil {
+		assert.True(t, efn.Equal(fn), "expected fieldname=%v, got %v", *efn, *fn)
 	}
 
 	annotations, err := r.Annotations()
-	if err != nil {
-		t.Errorf("annotations returned error: %v", err.Error())
+	assert.NoError(t, err)
 
-	}
-
-	if !_symbolTokenEquals(etas, annotations) {
-		t.Errorf("expected type annotations=%v, got %v", etas, annotations)
-	}
+	assert.True(t, _symbolTokenEquals(etas, annotations), "expected type annotations=%v, got %v", etas, annotations)
 }
 
 func _nextA(t *testing.T, r Reader, etas []SymbolToken, isAnnotationError bool, isNextError bool) {
@@ -940,13 +792,9 @@ func _nextA(t *testing.T, r Reader, etas []SymbolToken, isAnnotationError bool,
 	annotations, err := r.Annotations()
 
 	if isAnnotationError {
-		if err == nil {
-			t.Fatal("fieldName did not return an error")
-		}
+		require.Error(t, err)
 	} else {
-		if !_symbolTokenEquals(etas, annotations) {
-			t.Errorf("expected type annotations=%v, got %v", etas, annotations)
-		}
+		assert.True(t, _symbolTokenEquals(etas, annotations), "expected type annotations=%v, got %v", etas, annotations)
 	}
 }
 
@@ -958,21 +806,13 @@ func _nextF(t *testing.T, r Reader, efns *SymbolToken, isFieldNameError bool, is
 	fn, err := r.FieldName()
 
 	if isFieldNameError {
-		if err == nil {
-			t.Fatal("fieldName did not return an error")
-		}
+		require.Error(t, err, "fieldName did not return an error")
 	} else {
-		if err != nil {
-			t.Errorf("fieldname returned an error: %v", err.Error())
-		}
+		assert.NoError(t, err)
 		if efns != nil {
-			if !efns.Equal(fn) {
-				t.Errorf("expected fieldnamesymbol=%v, got %v", efns, fn)
-			}
+			assert.True(t, efns.Equal(fn), "expected fieldnamesymbol=%v, got %v", efns, fn)
 		} else {
-			if fn != nil {
-				t.Errorf("expected fieldnamesymbol=%v, got %v", efns, fn)
-			}
+			assert.Nil(t, fn, "expected fieldnamesymbol=%v, got %v", efns, fn)
 		}
 	}
 }
@@ -992,10 +832,6 @@ func _symbolTokenEquals(a, b []SymbolToken) bool {
 }
 
 func _eof(t *testing.T, r Reader) {
-	if r.Next() {
-		t.Fatal("next returned true")
-	}
-	if r.Err() != nil {
-		t.Fatal(r.Err())
-	}
+	require.False(t, r.Next())
+	require.NoError(t, r.Err())
 }
diff --git a/ion/textutils_test.go b/ion/textutils_test.go
index 4480772..735e9f2 100644
--- a/ion/textutils_test.go
+++ b/ion/textutils_test.go
@@ -19,26 +19,23 @@ import (
 	"strings"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestParseTimestamp(t *testing.T) {
 	test := func(str string, eval string, expectedPrecision TimestampPrecision, expectedKind TimezoneKind, expectedFractionSeconds uint8) {
 		t.Run(str, func(t *testing.T) {
 			val, err := parseTimestamp(str)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
 			et, err := time.Parse(time.RFC3339Nano, eval)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
 			expectedTimestamp := NewTimestampWithFractionalSeconds(et, expectedPrecision, expectedKind, expectedFractionSeconds)
 
-			if !val.Equal(expectedTimestamp) {
-				t.Errorf("expected %v, got %v", expectedTimestamp, val)
-			}
+			assert.True(t, val.Equal(expectedTimestamp), "expected %v, got %v", expectedTimestamp, val)
 		})
 	}
 
@@ -76,13 +73,9 @@ func TestWriteSymbol(t *testing.T) {
 	test := func(sym, expected string) {
 		t.Run(expected, func(t *testing.T) {
 			buf := strings.Builder{}
-			if err := writeSymbol(sym, &buf); err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, writeSymbol(sym, &buf))
 			actual := buf.String()
-			if actual != expected {
-				t.Errorf("expected \"%v\", got \"%v\"", expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 		})
 	}
 
@@ -104,9 +97,7 @@ func TestSymbolNeedsQuoting(t *testing.T) {
 	test := func(sym string, expected bool) {
 		t.Run(sym, func(t *testing.T) {
 			actual := symbolNeedsQuoting(sym)
-			if actual != expected {
-				t.Errorf("expected %v, got %v", expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 		})
 	}
 
@@ -139,14 +130,9 @@ func TestWriteEscapedSymbol(t *testing.T) {
 	test := func(sym, expected string) {
 		t.Run(expected, func(t *testing.T) {
 			buf := strings.Builder{}
-			if err := writeEscapedSymbol(sym, &buf); err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, writeEscapedSymbol(sym, &buf))
 			actual := buf.String()
-			if actual != expected {
-				t.Errorf("bad encoding of \"%v\": \"%v\"",
-					expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 		})
 	}
 
@@ -160,14 +146,9 @@ func TestWriteEscapedChar(t *testing.T) {
 	test := func(c byte, expected string) {
 		t.Run(expected, func(t *testing.T) {
 			buf := strings.Builder{}
-			if err := writeEscapedChar(c, &buf); err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, writeEscapedChar(c, &buf))
 			actual := buf.String()
-			if actual != expected {
-				t.Errorf("bad encoding of '%v': \"%v\"",
-					expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 		})
 	}
 
diff --git a/ion/textwriter_test.go b/ion/textwriter_test.go
index b644806..a4ad161 100644
--- a/ion/textwriter_test.go
+++ b/ion/textwriter_test.go
@@ -21,114 +21,97 @@ import (
 	"strings"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestWriteTextTopLevelFieldName(t *testing.T) {
 	writeText(func(w Writer) {
-		if err := w.FieldName("foo"); err == nil {
-			t.Error("expected an error")
-		}
+		assert.Error(t, w.FieldName("foo"))
 	})
 }
 
 func TestWriteTextEmptyStruct(t *testing.T) {
 	testTextWriter(t, "{}", func(w Writer) {
-		if err := w.BeginStruct(); err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, w.BeginStruct())
 
-		if err := w.EndStruct(); err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, w.EndStruct())
 
-		if err := w.EndStruct(); err == nil {
-			t.Fatal("no error from ending struct too many times")
-		}
+		require.Error(t, w.EndStruct())
 	})
 }
 
 func TestWriteTextAnnotatedStruct(t *testing.T) {
 	testTextWriter(t, "foo::$bar::'.baz'::{}", func(w Writer) {
-		w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown})
-		w.Annotation(SymbolToken{Text: newString("$bar"), LocalSID: SymbolIDUnknown})
-		w.Annotation(SymbolToken{Text: newString(".baz"), LocalSID: SymbolIDUnknown})
-		w.BeginStruct()
-		err := w.EndStruct()
-
-		if err != nil {
-			t.Fatal(err)
-		}
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("$bar"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString(".baz"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginStruct())
+		require.NoError(t, w.EndStruct())
 	})
 }
 
 func TestWriteTextNestedStruct(t *testing.T) {
 	testTextWriter(t, "{foo:'true'::{},'null':{}}", func(w Writer) {
-		w.BeginStruct()
+		assert.NoError(t, w.BeginStruct())
 
-		w.FieldName("foo")
-		w.Annotation(SymbolToken{Text: newString("true"), LocalSID: SymbolIDUnknown})
-		w.BeginStruct()
-		w.EndStruct()
+		assert.NoError(t, w.FieldName("foo"))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("true"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.EndStruct())
 
-		w.FieldName("null")
-		w.BeginStruct()
-		w.EndStruct()
+		assert.NoError(t, w.FieldName("null"))
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.EndStruct())
 
-		w.EndStruct()
+		assert.NoError(t, w.EndStruct())
 	})
 }
 
 func TestWriteTextEmptyList(t *testing.T) {
 	testTextWriter(t, "[]", func(w Writer) {
-		if err := w.BeginList(); err != nil {
-			t.Fatal(err)
-		}
-
-		if err := w.EndList(); err != nil {
-			t.Fatal(err)
-		}
-
-		if err := w.EndList(); err == nil {
-			t.Error("no error calling endlist at top level")
-		}
+		require.NoError(t, w.BeginList())
+		require.NoError(t, w.EndList())
+		require.Error(t, w.EndList())
 	})
 }
 
 func TestWriteTextNestedLists(t *testing.T) {
 	testTextWriter(t, "[{},foo::{},'null'::[]]", func(w Writer) {
-		w.BeginList()
+		assert.NoError(t, w.BeginList())
 
-		w.BeginStruct()
-		w.EndStruct()
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.EndStruct())
 
-		w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown})
-		w.BeginStruct()
-		w.EndStruct()
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.EndStruct())
 
-		w.Annotation(SymbolToken{Text: newString("null"), LocalSID: SymbolIDUnknown})
-		w.BeginList()
-		w.EndList()
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("null"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginList())
+		assert.NoError(t, w.EndList())
 
-		w.EndList()
+		assert.NoError(t, w.EndList())
 	})
 }
 
 func TestWriteTextSexps(t *testing.T) {
 	testTextWriter(t, "()\n(())\n(() ())", func(w Writer) {
-		w.BeginSexp()
-		w.EndSexp()
-
-		w.BeginSexp()
-		w.BeginSexp()
-		w.EndSexp()
-		w.EndSexp()
-
-		w.BeginSexp()
-		w.BeginSexp()
-		w.EndSexp()
-		w.BeginSexp()
-		w.EndSexp()
-		w.EndSexp()
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.EndSexp())
+
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.EndSexp())
+		assert.NoError(t, w.EndSexp())
+
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.EndSexp())
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.EndSexp())
+		assert.NoError(t, w.EndSexp())
 	})
 }
 
@@ -138,116 +121,116 @@ func TestWriteTextNulls(t *testing.T) {
 		"null.list,'null'::null.sexp,null.struct]"
 
 	testTextWriter(t, expected, func(w Writer) {
-		w.BeginList()
-
-		w.WriteNull()
-		w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown})
-		w.WriteNullType(NullType)
-		w.WriteNullType(BoolType)
-		w.WriteNullType(IntType)
-		w.WriteNullType(FloatType)
-		w.WriteNullType(DecimalType)
-		w.WriteNullType(TimestampType)
-		w.WriteNullType(SymbolType)
-		w.WriteNullType(StringType)
-		w.WriteNullType(ClobType)
-		w.WriteNullType(BlobType)
-		w.WriteNullType(ListType)
-		w.Annotation(SymbolToken{Text: newString("null"), LocalSID: SymbolIDUnknown})
-		w.WriteNullType(SexpType)
-		w.WriteNullType(StructType)
-
-		w.EndList()
+		assert.NoError(t, w.BeginList())
+
+		assert.NoError(t, w.WriteNull())
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("foo"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteNullType(NullType))
+		assert.NoError(t, w.WriteNullType(BoolType))
+		assert.NoError(t, w.WriteNullType(IntType))
+		assert.NoError(t, w.WriteNullType(FloatType))
+		assert.NoError(t, w.WriteNullType(DecimalType))
+		assert.NoError(t, w.WriteNullType(TimestampType))
+		assert.NoError(t, w.WriteNullType(SymbolType))
+		assert.NoError(t, w.WriteNullType(StringType))
+		assert.NoError(t, w.WriteNullType(ClobType))
+		assert.NoError(t, w.WriteNullType(BlobType))
+		assert.NoError(t, w.WriteNullType(ListType))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("null"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteNullType(SexpType))
+		assert.NoError(t, w.WriteNullType(StructType))
+
+		assert.NoError(t, w.EndList())
 	})
 }
 
 func TestWriteTextBool(t *testing.T) {
 	expected := "true\n(false '123'::true)\n'false'::false"
 	testTextWriter(t, expected, func(w Writer) {
-		w.WriteBool(true)
+		assert.NoError(t, w.WriteBool(true))
 
-		w.BeginSexp()
+		assert.NoError(t, w.BeginSexp())
 
-		w.WriteBool(false)
-		w.Annotation(SymbolToken{Text: newString("123"), LocalSID: SymbolIDUnknown})
-		w.WriteBool(true)
+		assert.NoError(t, w.WriteBool(false))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("123"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteBool(true))
 
-		w.EndSexp()
+		assert.NoError(t, w.EndSexp())
 
-		w.Annotation(SymbolToken{Text: newString("false"), LocalSID: SymbolIDUnknown})
-		w.WriteBool(false)
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("false"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteBool(false))
 	})
 }
 
 func TestWriteTextInt(t *testing.T) {
 	expected := "(zero::0 1 -1 (9223372036854775807 -9223372036854775808))"
 	testTextWriter(t, expected, func(w Writer) {
-		w.BeginSexp()
+		assert.NoError(t, w.BeginSexp())
 
-		w.Annotation(SymbolToken{Text: newString("zero"), LocalSID: SymbolIDUnknown})
-		w.WriteInt(0)
-		w.WriteInt(1)
-		w.WriteInt(-1)
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("zero"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteInt(0))
+		assert.NoError(t, w.WriteInt(1))
+		assert.NoError(t, w.WriteInt(-1))
 
-		w.BeginSexp()
-		w.WriteInt(math.MaxInt64)
-		w.WriteInt(math.MinInt64)
-		w.EndSexp()
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.WriteInt(math.MaxInt64))
+		assert.NoError(t, w.WriteInt(math.MinInt64))
+		assert.NoError(t, w.EndSexp())
 
-		w.EndSexp()
+		assert.NoError(t, w.EndSexp())
 	})
 }
 
 func TestWriteTextBigInt(t *testing.T) {
 	expected := "[0,big::18446744073709551616]"
 	testTextWriter(t, expected, func(w Writer) {
-		w.BeginList()
+		assert.NoError(t, w.BeginList())
 
-		w.WriteBigInt(big.NewInt(0))
+		assert.NoError(t, w.WriteBigInt(big.NewInt(0)))
 
 		var val, max, one big.Int
 		max.SetUint64(math.MaxUint64)
 		one.SetInt64(1)
 		val.Add(&max, &one)
 
-		w.Annotation(SymbolToken{Text: newString("big"), LocalSID: SymbolIDUnknown})
-		w.WriteBigInt(&val)
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("big"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteBigInt(&val))
 
-		w.EndList()
+		assert.NoError(t, w.EndList())
 	})
 }
 
 func TestWriteTextFloat(t *testing.T) {
 	expected := "{z:0e+0,nz:-0e+0,s:1.234e+1,l:1.234e-55,n:nan,i:+inf,ni:-inf}"
 	testTextWriter(t, expected, func(w Writer) {
-		w.BeginStruct()
-
-		w.FieldName("z")
-		w.WriteFloat(0.0)
-		w.FieldName("nz")
-		w.WriteFloat(-1.0 / math.Inf(1))
-
-		w.FieldName("s")
-		w.WriteFloat(12.34)
-		w.FieldName("l")
-		w.WriteFloat(12.34e-56)
-
-		w.FieldName("n")
-		w.WriteFloat(math.NaN())
-		w.FieldName("i")
-		w.WriteFloat(math.Inf(1))
-		w.FieldName("ni")
-		w.WriteFloat(math.Inf(-1))
-
-		w.EndStruct()
+		assert.NoError(t, w.BeginStruct())
+
+		assert.NoError(t, w.FieldName("z"))
+		assert.NoError(t, w.WriteFloat(0.0))
+		assert.NoError(t, w.FieldName("nz"))
+		assert.NoError(t, w.WriteFloat(-1.0/math.Inf(1)))
+
+		assert.NoError(t, w.FieldName("s"))
+		assert.NoError(t, w.WriteFloat(12.34))
+		assert.NoError(t, w.FieldName("l"))
+		assert.NoError(t, w.WriteFloat(12.34e-56))
+
+		assert.NoError(t, w.FieldName("n"))
+		assert.NoError(t, w.WriteFloat(math.NaN()))
+		assert.NoError(t, w.FieldName("i"))
+		assert.NoError(t, w.WriteFloat(math.Inf(1)))
+		assert.NoError(t, w.FieldName("ni"))
+		assert.NoError(t, w.WriteFloat(math.Inf(-1)))
+
+		assert.NoError(t, w.EndStruct())
 	})
 }
 
 func TestWriteTextDecimal(t *testing.T) {
 	expected := "0.\n-1.23d-98"
 	testTextWriter(t, expected, func(w Writer) {
-		w.WriteDecimal(MustParseDecimal("0"))
-		w.WriteDecimal(MustParseDecimal("-123d-100"))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("0")))
+		assert.NoError(t, w.WriteDecimal(MustParseDecimal("-123d-100")))
 	})
 }
 
@@ -255,87 +238,85 @@ func TestWriteTextTimestamp(t *testing.T) {
 	expected := "1970-01-01T00:00:00.001Z\n1970-01-01T01:23:00+01:23"
 	testTextWriter(t, expected, func(w Writer) {
 		dateTime := time.Unix(0, 1000000).In(time.UTC)
-		w.WriteTimestamp(NewTimestampWithFractionalSeconds(dateTime, TimestampPrecisionNanosecond, TimezoneUTC, 3))
+		assert.NoError(t, w.WriteTimestamp(NewTimestampWithFractionalSeconds(dateTime, TimestampPrecisionNanosecond, TimezoneUTC, 3)))
 		dateTime = time.Unix(0, 0).In(time.FixedZone("foo", 4980))
-		w.WriteTimestamp(NewTimestamp(dateTime, TimestampPrecisionSecond, TimezoneLocal))
+		assert.NoError(t, w.WriteTimestamp(NewTimestamp(dateTime, TimestampPrecisionSecond, TimezoneLocal)))
 	})
 }
 
 func TestWriteTextSymbol(t *testing.T) {
 	expected := "{foo:bar,empty:'','null':'null',f:a::b::u::'lo🇺🇸',$123:$456}"
 	testTextWriter(t, expected, func(w Writer) {
-		w.BeginStruct()
+		assert.NoError(t, w.BeginStruct())
 
-		w.FieldName("foo")
-		w.WriteSymbol("bar")
-		w.FieldName("empty")
-		w.WriteSymbol("")
-		w.FieldName("null")
-		w.WriteSymbol("null")
+		assert.NoError(t, w.FieldName("foo"))
+		assert.NoError(t, w.WriteSymbol("bar"))
+		assert.NoError(t, w.FieldName("empty"))
+		assert.NoError(t, w.WriteSymbol(""))
+		assert.NoError(t, w.FieldName("null"))
+		assert.NoError(t, w.WriteSymbol("null"))
 
-		w.FieldName("f")
-		w.Annotation(SymbolToken{Text: newString("a"), LocalSID: SymbolIDUnknown})
-		w.Annotation(SymbolToken{Text: newString("b"), LocalSID: SymbolIDUnknown})
-		w.Annotation(SymbolToken{Text: newString("u"), LocalSID: SymbolIDUnknown})
-		w.WriteSymbol("lo🇺🇸")
+		assert.NoError(t, w.FieldName("f"))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("a"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("b"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("u"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteSymbol("lo🇺🇸"))
 
-		w.FieldName("$123")
-		w.WriteSymbol("$456")
+		assert.NoError(t, w.FieldName("$123"))
+		assert.NoError(t, w.WriteSymbol("$456"))
 
-		w.EndStruct()
+		assert.NoError(t, w.EndStruct())
 	})
 }
 
 func TestWriteTextString(t *testing.T) {
 	expected := `("hello" "" ("\\\"\n\"\\" zany::"🤪"))`
 	testTextWriter(t, expected, func(w Writer) {
-		w.BeginSexp()
-		w.WriteString("hello")
-		w.WriteString("")
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.WriteString("hello"))
+		assert.NoError(t, w.WriteString(""))
 
-		w.BeginSexp()
-		w.WriteString("\\\"\n\"\\")
-		w.Annotation(SymbolToken{Text: newString("zany"), LocalSID: SymbolIDUnknown})
-		w.WriteString("🤪")
-		w.EndSexp()
+		assert.NoError(t, w.BeginSexp())
+		assert.NoError(t, w.WriteString("\\\"\n\"\\"))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("zany"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteString("🤪"))
+		assert.NoError(t, w.EndSexp())
 
-		w.EndSexp()
+		assert.NoError(t, w.EndSexp())
 	})
 }
 
 func TestWriteTextBlob(t *testing.T) {
 	expected := "{{AAEC/f7/}}\n{{SGVsbG8gV29ybGQ=}}\nempty::{{}}"
 	testTextWriter(t, expected, func(w Writer) {
-		w.WriteBlob([]byte{0, 1, 2, 0xFD, 0xFE, 0xFF})
-		w.WriteBlob([]byte("Hello World"))
-		w.Annotation(SymbolToken{Text: newString("empty"), LocalSID: SymbolIDUnknown})
-		w.WriteBlob(nil)
+		assert.NoError(t, w.WriteBlob([]byte{0, 1, 2, 0xFD, 0xFE, 0xFF}))
+		assert.NoError(t, w.WriteBlob([]byte("Hello World")))
+		assert.NoError(t, w.Annotation(SymbolToken{Text: newString("empty"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.WriteBlob(nil))
 	})
 }
 
 func TestWriteTextClob(t *testing.T) {
 	expected := "{hello:{{\"world\"}},bits:{{\"\\0\\x01\\xFE\\xFF\"}}}"
 	testTextWriter(t, expected, func(w Writer) {
-		w.BeginStruct()
-		w.FieldName("hello")
-		w.WriteClob([]byte("world"))
-		w.FieldName("bits")
-		w.WriteClob([]byte{0, 1, 0xFE, 0xFF})
-		w.EndStruct()
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.FieldName("hello"))
+		assert.NoError(t, w.WriteClob([]byte("world")))
+		assert.NoError(t, w.FieldName("bits"))
+		assert.NoError(t, w.WriteClob([]byte{0, 1, 0xFE, 0xFF}))
+		assert.NoError(t, w.EndStruct())
 	})
 }
 
 func TestWriteTextFinish(t *testing.T) {
 	expected := "1\nfoo\n\"bar\"\n{}\n"
 	testTextWriter(t, expected, func(w Writer) {
-		w.WriteInt(1)
-		w.WriteSymbol("foo")
-		w.WriteString("bar")
-		w.BeginStruct()
-		w.EndStruct()
-		if err := w.Finish(); err != nil {
-			t.Fatal(err)
-		}
+		assert.NoError(t, w.WriteInt(1))
+		assert.NoError(t, w.WriteSymbol("foo"))
+		assert.NoError(t, w.WriteString("bar"))
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.EndStruct())
+		require.NoError(t, w.Finish())
 	})
 }
 
@@ -343,61 +324,59 @@ func TestWriteTextBadFinish(t *testing.T) {
 	buf := strings.Builder{}
 	w := NewTextWriter(&buf)
 
-	w.BeginStruct()
-	err := w.Finish()
-
-	if err == nil {
-		t.Error("should not be able to finish in the middle of a struct")
-	}
+	assert.NoError(t, w.BeginStruct())
+	require.Error(t, w.Finish())
 }
 
 func TestWriteTextPretty(t *testing.T) {
 	buf := strings.Builder{}
 	w := NewTextWriterOpts(&buf, TextWriterPretty)
 
-	w.BeginStruct()
+	assert.NoError(t, w.BeginStruct())
 	{
-		w.FieldName("struct")
-		w.BeginStruct()
-		w.EndStruct()
-
-		w.FieldName("list")
-		w.Annotations(SymbolToken{Text: newString("i"), LocalSID: SymbolIDUnknown}, SymbolToken{Text: newString("am"), LocalSID: SymbolIDUnknown}, SymbolToken{Text: newString("a"), LocalSID: SymbolIDUnknown}, SymbolToken{Text: newString("list"), LocalSID: SymbolIDUnknown})
-		w.BeginList()
+		assert.NoError(t, w.FieldName("struct"))
+		assert.NoError(t, w.BeginStruct())
+		assert.NoError(t, w.EndStruct())
+
+		assert.NoError(t, w.FieldName("list"))
+		assert.NoError(t, w.Annotations(
+			SymbolToken{Text: newString("i"), LocalSID: SymbolIDUnknown},
+			SymbolToken{Text: newString("am"), LocalSID: SymbolIDUnknown},
+			SymbolToken{Text: newString("a"), LocalSID: SymbolIDUnknown},
+			SymbolToken{Text: newString("list"), LocalSID: SymbolIDUnknown}))
+		assert.NoError(t, w.BeginList())
 		{
-			w.WriteString("value")
-			w.WriteNullType(StringType)
-			w.BeginStruct()
+			assert.NoError(t, w.WriteString("value"))
+			assert.NoError(t, w.WriteNullType(StringType))
+			assert.NoError(t, w.BeginStruct())
 			{
-				w.FieldName("1")
-				w.WriteString("one")
-				w.FieldName("2")
-				w.WriteString("two")
+				assert.NoError(t, w.FieldName("1"))
+				assert.NoError(t, w.WriteString("one"))
+				assert.NoError(t, w.FieldName("2"))
+				assert.NoError(t, w.WriteString("two"))
 			}
-			w.EndStruct()
+			assert.NoError(t, w.EndStruct())
 		}
-		w.EndList()
+		assert.NoError(t, w.EndList())
 
-		w.FieldName("sexp")
-		w.BeginSexp()
+		assert.NoError(t, w.FieldName("sexp"))
+		assert.NoError(t, w.BeginSexp())
 		{
-			w.WriteSymbol("+")
-			w.WriteInt(123)
-			w.BeginSexp()
+			assert.NoError(t, w.WriteSymbol("+"))
+			assert.NoError(t, w.WriteInt(123))
+			assert.NoError(t, w.BeginSexp())
 			{
-				w.WriteSymbol("*")
-				w.WriteInt(456)
-				w.WriteInt(789)
+				assert.NoError(t, w.WriteSymbol("*"))
+				assert.NoError(t, w.WriteInt(456))
+				assert.NoError(t, w.WriteInt(789))
 			}
-			w.EndSexp()
+			assert.NoError(t, w.EndSexp())
 		}
-		w.EndSexp()
+		assert.NoError(t, w.EndSexp())
 	}
-	w.EndStruct()
+	assert.NoError(t, w.EndStruct())
 
-	if err := w.Finish(); err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, w.Finish())
 
 	actual := buf.String()
 	expected := `{
@@ -421,16 +400,12 @@ func TestWriteTextPretty(t *testing.T) {
 	)
 }
 `
-	if actual != expected {
-		t.Errorf("expected:\n%v\ngot:\n%v", expected, actual)
-	}
+	assert.Equal(t, expected, actual)
 }
 
 func testTextWriter(t *testing.T, expected string, f func(Writer)) {
 	actual := writeText(f)
-	if actual != expected {
-		t.Errorf("expected: %v, actual: %v", expected, actual)
-	}
+	assert.Equal(t, expected, actual)
 }
 
 func writeText(f func(Writer)) string {
diff --git a/ion/timestamp_test.go b/ion/timestamp_test.go
index 2c2c67d..688d983 100644
--- a/ion/timestamp_test.go
+++ b/ion/timestamp_test.go
@@ -18,6 +18,9 @@ package ion
 import (
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestNewTimestampFromStr(t *testing.T) {
@@ -105,12 +108,8 @@ func TestNewTimestampFromStr(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.testCase, func(t *testing.T) {
 			actual, err := NewTimestampFromStr(tt.args.dateStr, tt.args.precision, tt.args.kind)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !actual.Equal(tt.expected) {
-				t.Fatalf("expected %v, got %v", tt.expected, actual)
-			}
+			require.NoError(t, err)
+			assert.True(t, actual.Equal(tt.expected), "expected %v, got %v", tt.expected, actual)
 		})
 	}
 }
@@ -205,9 +204,7 @@ func TestTimestampString(t *testing.T) {
 				kind:                 kind,
 				numFractionalSeconds: tt.fields.numFractionalSeconds,
 			}
-			if actual := ts.String(); actual != tt.expected {
-				t.Fatalf("expected %v, got %v", tt.expected, actual)
-			}
+			assert.Equal(t, tt.expected, ts.String())
 		})
 	}
 }
diff --git a/ion/tokenizer_test.go b/ion/tokenizer_test.go
index 24de682..e633c37 100644
--- a/ion/tokenizer_test.go
+++ b/ion/tokenizer_test.go
@@ -18,18 +18,17 @@ package ion
 import (
 	"io"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestNext(t *testing.T) {
 	tok := tokenizeString("foo::'foo':[] 123, {})")
 
 	next := func(tt token) {
-		if err := tok.Next(); err != nil {
-			t.Fatal(err)
-		}
-		if tok.Token() != tt {
-			t.Fatalf("expected %v, got %v", tt, tok.Token())
-		}
+		require.NoError(t, tok.Next())
+		require.Equal(t, tt, tok.Token())
 	}
 
 	next(tokenSymbol)
@@ -46,29 +45,17 @@ func TestReadSymbol(t *testing.T) {
 	test := func(str string, expected string, next token) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
-			if err := tok.Next(); err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, tok.Next())
 
-			if tok.Token() != tokenSymbol {
-				t.Fatal("not a symbol")
-			}
+			require.Equal(t, tokenSymbol, tok.Token())
 
 			actual, err := tok.readSymbol()
-			if err != nil {
-				t.Fatal(err)
-			}
-
-			if actual != expected {
-				t.Errorf("expected '%v', got '%v'", expected, actual)
-			}
-
-			if err := tok.Next(); err != nil {
-				t.Fatal(err)
-			}
-			if tok.Token() != next {
-				t.Errorf("expected next=%v, got next=%v", next, tok.Token())
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, expected, actual)
+
+			require.NoError(t, tok.Next())
+			assert.Equal(t, next, tok.Token())
 		})
 	}
 
@@ -84,21 +71,13 @@ func TestReadSymbols(t *testing.T) {
 	expected := []string{"foo", "bar", "baz", "beep", "boop", "null"}
 
 	for i := 0; i < len(expected); i++ {
-		if err := tok.Next(); err != nil {
-			t.Fatal(err)
-		}
-		if tok.Token() != tokenSymbol {
-			t.Fatalf("expected %v, got %v", tokenSymbol, tok.Token())
-		}
+		require.NoError(t, tok.Next())
+		require.Equal(t, tokenSymbol, tok.Token())
 
 		val, err := tok.readSymbol()
-		if err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, err)
 
-		if val != expected[i] {
-			t.Errorf("expected %v, got %v", expected[i], val)
-		}
+		assert.Equal(t, expected[i], val)
 	}
 }
 
@@ -106,30 +85,19 @@ func TestReadQuotedSymbol(t *testing.T) {
 	test := func(str string, expected string, next int) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
-			if err := tok.Next(); err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, tok.Next())
 
-			if tok.Token() != tokenSymbolQuoted {
-				t.Fatal("not a quoted symbol")
-			}
+			require.Equal(t, tokenSymbolQuoted, tok.Token())
 
 			actual, err := tok.readQuotedSymbol()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
-			if actual != expected {
-				t.Errorf("expected '%v', got '%v'", expected, actual)
-			}
+			assert.Equal(t, expected, actual)
 
 			c, err := tok.read()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if c != next {
-				t.Errorf("expected next=%q, got next=%q", next, c)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, next, c)
 		})
 	}
 
@@ -151,28 +119,19 @@ func TestReadTimestamp(t *testing.T) {
 	test := func(str string, eval string, next int) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
-			if err := tok.Next(); err != nil {
-				t.Fatal(err)
-			}
-			if tok.Token() != tokenTimestamp {
-				t.Fatalf("unexpected token %v", tok.Token())
-			}
+			require.NoError(t, tok.Next())
+
+			require.Equal(t, tokenTimestamp, tok.Token())
 
 			val, err := tok.ReadValue(tokenTimestamp)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, eval, val)
 
 			c, err := tok.read()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if c != next {
-				t.Errorf("expected %q, got %q", next, c)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, next, c)
 		})
 	}
 
@@ -198,12 +157,9 @@ func TestIsTripleQuote(t *testing.T) {
 			tok := tokenizeString(str)
 
 			ok, err := tok.IsTripleQuote()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if ok != eok {
-				t.Errorf("expected ok=%v, got ok=%v", eok, ok)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, eok, ok)
 
 			read(t, tok, next)
 		})
@@ -220,26 +176,17 @@ func TestIsInf(t *testing.T) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
 			c, err := tok.read()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
 			ok, err := tok.isInf(c)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
-			if ok != eok {
-				t.Errorf("expected %v, got %v", eok, ok)
-			}
+			assert.Equal(t, eok, ok)
 
 			c, err = tok.read()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if c != next {
-				t.Errorf("expected '%c', got '%c'", next, c)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, next, c)
 		})
 	}
 
@@ -273,17 +220,12 @@ func TestScanForNumericType(t *testing.T) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
 			c, err := tok.read()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
 
 			tt, err := tok.scanForNumericType(c)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if tt != ett {
-				t.Errorf("expected %v, got %v", ett, tt)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, ett, tt)
 		})
 	}
 
@@ -311,16 +253,10 @@ func TestSkipWhitespace(t *testing.T) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
 			c, ok, err := tok.skipWhitespace()
-			if err != nil {
-				t.Fatal(err)
-			}
-
-			if ok != eok {
-				t.Errorf("expected ok=%v, got ok=%v", eok, ok)
-			}
-			if c != ec {
-				t.Errorf("expected c='%c', got c='%c'", ec, c)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, eok, ok)
+			assert.Equal(t, ec, c)
 		})
 	}
 
@@ -338,16 +274,10 @@ func TestSkipLobWhitespace(t *testing.T) {
 		t.Run(str, func(t *testing.T) {
 			tok := tokenizeString(str)
 			c, ok, err := tok.skipLobWhitespace()
-			if err != nil {
-				t.Fatal(err)
-			}
-
-			if ok != eok {
-				t.Errorf("expected ok=%v, got ok=%v", eok, ok)
-			}
-			if c != ec {
-				t.Errorf("expected c='%c', got c='%c'", ec, c)
-			}
+			require.NoError(t, err)
+
+			assert.Equal(t, eok, ok)
+			assert.Equal(t, ec, c)
 		})
 	}
 
@@ -363,12 +293,9 @@ func TestSkipCommentsHandler(t *testing.T) {
 	t.Run("SingleLine", func(t *testing.T) {
 		tok := tokenizeString("/comment\nok")
 		ok, err := tok.skipCommentsHandler()
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !ok {
-			t.Error("expected ok=true, got ok=false")
-		}
+		require.NoError(t, err)
+
+		assert.True(t, ok)
 
 		read(t, tok, 'o')
 		read(t, tok, 'k')
@@ -378,12 +305,9 @@ func TestSkipCommentsHandler(t *testing.T) {
 	t.Run("Block", func(t *testing.T) {
 		tok := tokenizeString("*comm\nent*/ok")
 		ok, err := tok.skipCommentsHandler()
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !ok {
-			t.Error("expected ok=true, got ok=false")
-		}
+		require.NoError(t, err)
+
+		assert.True(t, ok)
 
 		read(t, tok, 'o')
 		read(t, tok, 'k')
@@ -393,12 +317,9 @@ func TestSkipCommentsHandler(t *testing.T) {
 	t.Run("FalseAlarm", func(t *testing.T) {
 		tok := tokenizeString(" 0)")
 		ok, err := tok.skipCommentsHandler()
-		if err != nil {
-			t.Fatal(err)
-		}
-		if ok {
-			t.Error("expected ok=false, got ok=true")
-		}
+		require.NoError(t, err)
+
+		assert.False(t, ok)
 
 		read(t, tok, ' ')
 		read(t, tok, '0')
@@ -409,10 +330,7 @@ func TestSkipCommentsHandler(t *testing.T) {
 
 func TestSkipSingleLineComment(t *testing.T) {
 	tok := tokenizeString("single-line comment\r\nok")
-	err := tok.skipSingleLineComment()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, tok.skipSingleLineComment())
 
 	read(t, tok, 'o')
 	read(t, tok, 'k')
@@ -421,20 +339,14 @@ func TestSkipSingleLineComment(t *testing.T) {
 
 func TestSkipSingleLineCommentOnLastLine(t *testing.T) {
 	tok := tokenizeString("single-line comment")
-	err := tok.skipSingleLineComment()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, tok.skipSingleLineComment())
 
 	read(t, tok, -1)
 }
 
 func TestSkipBlockComment(t *testing.T) {
 	tok := tokenizeString("this is/ a\nmulti-line /** comment.**/ok")
-	err := tok.skipBlockComment()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, tok.skipBlockComment())
 
 	read(t, tok, 'o')
 	read(t, tok, 'k')
@@ -443,10 +355,7 @@ func TestSkipBlockComment(t *testing.T) {
 
 func TestSkipInvalidBlockComment(t *testing.T) {
 	tok := tokenizeString("this is a comment that never ends")
-	err := tok.skipBlockComment()
-	if err == nil {
-		t.Error("did not fail on bad block comment")
-	}
+	require.Error(t, tok.skipBlockComment())
 }
 
 func TestPeekN(t *testing.T) {
@@ -480,12 +389,8 @@ func TestPeekN(t *testing.T) {
 
 func peekN(t *testing.T, tok *tokenizer, n int, ee error, ecs ...int) {
 	cs, err := tok.peekN(n)
-	if err != ee {
-		t.Fatalf("expected err=%v, got err=%v", ee, err)
-	}
-	if !equal(ecs, cs) {
-		t.Errorf("expected %v, got %v", ecs, cs)
-	}
+	require.Equal(t, ee, err)
+	assert.True(t, equal(ecs, cs), "expected %v, got %v", ecs, cs)
 }
 
 func equal(a, b []int) bool {
@@ -526,12 +431,9 @@ func TestPeek(t *testing.T) {
 
 func peek(t *testing.T, tok *tokenizer, expected int) {
 	c, err := tok.peek()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if c != expected {
-		t.Errorf("expected %v, got %v", expected, c)
-	}
+	require.NoError(t, err)
+
+	assert.Equal(t, expected, c)
 }
 
 func TestReadUnread(t *testing.T) {
@@ -568,19 +470,13 @@ func TestReadUnread(t *testing.T) {
 
 func TestTokenToString(t *testing.T) {
 	for i := tokenError; i <= tokenCloseDoubleBrace+1; i++ {
-		str := i.String()
-		if str == "" {
-			t.Errorf("expected non-empty string for token %v", int(i))
-		}
+		assert.NotEmpty(t, i.String(), "expected non-empty string for token %v", int(i))
 	}
 }
 
 func read(t *testing.T, tok *tokenizer, expected int) {
 	c, err := tok.read()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if c != expected {
-		t.Errorf("expected %v, got %v", expected, c)
-	}
+	require.NoError(t, err)
+
+	assert.Equal(t, expected, c)
 }
diff --git a/ion/type_test.go b/ion/type_test.go
index 362a63a..13114d5 100644
--- a/ion/type_test.go
+++ b/ion/type_test.go
@@ -15,23 +15,21 @@
 
 package ion
 
-import "testing"
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
 
 func TestTypeToString(t *testing.T) {
 	for i := NoType; i <= StructType+1; i++ {
-		str := i.String()
-		if str == "" {
-			t.Errorf("expected a non-empty string for type %v", uint8(i))
-		}
+		assert.NotEmpty(t, i.String(), "expected a non-empty string for type %v", uint8(i))
 	}
 }
 
 func TestIntSizeToString(t *testing.T) {
 	for i := NullInt; i <= BigInt+1; i++ {
-		str := i.String()
-		if str == "" {
-			t.Errorf("expected a non-empty string for size %v", uint8(i))
-		}
+		assert.NotEmpty(t, i.String(), "expected a non-empty string for type %v", uint8(i))
 	}
 }
 
@@ -40,17 +38,13 @@ func TestIsScalar(t *testing.T) {
 		TimestampType, SymbolType, StringType, ClobType, BlobType}
 
 	for _, ionType := range scalarTypes {
-		if !IsScalar(ionType) {
-			t.Errorf("Expected IsScalar() to return true for type %s", ionType.String())
-		}
+		assert.True(t, IsScalar(ionType))
 	}
 
 	nonScalarTypes := []Type{NoType, ListType, SexpType, StructType}
 
 	for _, ionType := range nonScalarTypes {
-		if IsScalar(ionType) {
-			t.Errorf("Expected IsScalar() to return false for type %s", ionType.String())
-		}
+		assert.False(t, IsScalar(ionType))
 	}
 }
 
@@ -58,17 +52,13 @@ func TestIsContainer(t *testing.T) {
 	containerTypes := []Type{ListType, SexpType, StructType}
 
 	for _, ionType := range containerTypes {
-		if !IsContainer(ionType) {
-			t.Errorf("Expected IsContainer() to return true for type %s", ionType.String())
-		}
+		assert.True(t, IsContainer(ionType))
 	}
 
 	nonContainerTypes := []Type{NoType, NullType, BoolType, IntType, FloatType, DecimalType,
 		TimestampType, SymbolType, StringType, ClobType, BlobType}
 
 	for _, ionType := range nonContainerTypes {
-		if IsContainer(ionType) {
-			t.Errorf("Expected IsContainer() to return false for type %s", ionType.String())
-		}
+		assert.False(t, IsContainer(ionType))
 	}
 }
diff --git a/ion/unmarshal_test.go b/ion/unmarshal_test.go
index 7310e37..8d69fa8 100644
--- a/ion/unmarshal_test.go
+++ b/ion/unmarshal_test.go
@@ -22,20 +22,18 @@ import (
 	"reflect"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestUnmarshalBool(t *testing.T) {
 	test := func(str string, eval bool) {
 		t.Run(str, func(t *testing.T) {
 			var val bool
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -49,15 +47,10 @@ func TestUnmarshalBoolPtr(t *testing.T) {
 		t.Run(str, func(t *testing.T) {
 			var bval bool
 			val := &bval
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
 			if eval == nil {
-				if val != nil {
-					t.Errorf("expected <nil>, got %v", *val)
-				}
+				assert.Nil(t, val)
 			} else {
 				switch {
 				case val == nil:
@@ -79,14 +72,9 @@ func TestUnmarshalInt(t *testing.T) {
 	testInt8 := func(str string, eval int8) {
 		t.Run(str, func(t *testing.T) {
 			var val int8
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testInt8("null", 0)
@@ -97,14 +85,9 @@ func TestUnmarshalInt(t *testing.T) {
 	testInt16 := func(str string, eval int16) {
 		t.Run(str, func(t *testing.T) {
 			var val int16
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testInt16("0x7F", 0x7F)
@@ -115,14 +98,9 @@ func TestUnmarshalInt(t *testing.T) {
 	testInt32 := func(str string, eval int32) {
 		t.Run(str, func(t *testing.T) {
 			var val int32
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testInt32("0x7FFF", 0x7FFF)
@@ -133,14 +111,9 @@ func TestUnmarshalInt(t *testing.T) {
 	testInt := func(str string, eval int) {
 		t.Run(str, func(t *testing.T) {
 			var val int
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testInt("0x7FFF", 0x7FFF)
@@ -151,14 +124,9 @@ func TestUnmarshalInt(t *testing.T) {
 	testInt64 := func(str string, eval int64) {
 		t.Run(str, func(t *testing.T) {
 			var val int64
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testInt64("0x7FFFFFFF", 0x7FFFFFFF)
@@ -171,14 +139,9 @@ func TestUnmarshalUint(t *testing.T) {
 	testUint8 := func(str string, eval uint8) {
 		t.Run(str, func(t *testing.T) {
 			var val uint8
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testUint8("null", 0)
@@ -188,14 +151,9 @@ func TestUnmarshalUint(t *testing.T) {
 	testUint16 := func(str string, eval uint16) {
 		t.Run(str, func(t *testing.T) {
 			var val uint16
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testUint16("0xFF", 0xFF)
@@ -204,14 +162,9 @@ func TestUnmarshalUint(t *testing.T) {
 	testUint32 := func(str string, eval uint32) {
 		t.Run(str, func(t *testing.T) {
 			var val uint32
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testUint32("0xFFFF", 0xFFFF)
@@ -220,14 +173,9 @@ func TestUnmarshalUint(t *testing.T) {
 	testUint := func(str string, eval uint) {
 		t.Run(str, func(t *testing.T) {
 			var val uint
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testUint("0xFFFF", 0xFFFF)
@@ -236,14 +184,9 @@ func TestUnmarshalUint(t *testing.T) {
 	testUintptr := func(str string, eval uintptr) {
 		t.Run(str, func(t *testing.T) {
 			var val uintptr
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testUintptr("0xFFFF", 0xFFFF)
@@ -252,14 +195,9 @@ func TestUnmarshalUint(t *testing.T) {
 	testUint64 := func(str string, eval uint64) {
 		t.Run(str, func(t *testing.T) {
 			var val uint64
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	testUint64("0xFFFFFFFF", 0xFFFFFFFF)
@@ -270,14 +208,9 @@ func TestUnmarshalBigInt(t *testing.T) {
 	test := func(str string, eval *big.Int) {
 		t.Run(str, func(t *testing.T) {
 			var val big.Int
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if val.Cmp(eval) != 0 {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, val.Cmp(eval) == 0, "expected %v, got %v", eval, val)
 		})
 	}
 	test("null", new(big.Int))
@@ -288,10 +221,8 @@ func TestUnmarshalBigInt(t *testing.T) {
 func TestUnmarshalBinary(t *testing.T) {
 	test := func(data []byte, val, eval interface{}) {
 		t.Run(reflect.TypeOf(val).String(), func(t *testing.T) {
-			err := Unmarshal(data, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, Unmarshal(data, &val))
+
 			res := false
 			switch thisValue := val.(type) {
 			case *Decimal:
@@ -308,9 +239,7 @@ func TestUnmarshalBinary(t *testing.T) {
 			default:
 				res = reflect.DeepEqual(val, eval)
 			}
-			if !res {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, res, "expected %v, got %v", eval, val)
 		})
 	}
 
@@ -364,14 +293,9 @@ func TestUnmarshalBinary(t *testing.T) {
 func TestUnmarshalStructBinary(t *testing.T) {
 	test := func(data []byte, testName string, val, eval interface{}) {
 		t.Run(testName, func(t *testing.T) {
-			err := Unmarshal(data, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, Unmarshal(data, &val))
 
-			if !reflect.DeepEqual(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -395,14 +319,9 @@ func TestUnmarshalStructBinary(t *testing.T) {
 func TestUnmarshalListSexpBinary(t *testing.T) {
 	test := func(data []byte, testName string, val, eval interface{}) {
 		t.Run("reflect.TypeOf(val).String()", func(t *testing.T) {
-			err := Unmarshal(data, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, Unmarshal(data, &val))
 
-			if !reflect.DeepEqual(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -423,14 +342,9 @@ func TestDecodeFloat(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
 
 			var val float32
-			err := d.DecodeTo(&val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, d.DecodeTo(&val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	test32("null", 0)
@@ -443,14 +357,9 @@ func TestDecodeFloat(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
 
 			var val float64
-			err := d.DecodeTo(&val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, d.DecodeTo(&val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 	test64("1e0", 1)
@@ -464,14 +373,9 @@ func TestDecodeDecimal(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
 
 			var val *Decimal
-			err := d.DecodeTo(&val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, d.DecodeTo(&val))
 
-			if !val.Equal(eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, val.Equal(eval), "expected %v, got %v", eval, val)
 		})
 	}
 
@@ -485,14 +389,9 @@ func TestDecodeTimestampTo(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
 
 			var val Timestamp
-			err := d.DecodeTo(&val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, d.DecodeTo(&val))
 
-			if !val.Equal(eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, val.Equal(eval), "expected %v, got %v", eval, val)
 		})
 	}
 	test("null", Timestamp{})
@@ -505,14 +404,9 @@ func TestDecodeStringTo(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
 
 			var val string
-			err := d.DecodeTo(&val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, d.DecodeTo(&val))
 
-			if val != eval {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -527,14 +421,9 @@ func TestDecodeLobTo(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
 
 			var val []byte
-			err := d.DecodeTo(&val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, d.DecodeTo(&val))
 
-			if !bytes.Equal(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, bytes.Equal(val, eval), "expected %v, got %v", eval, val)
 		})
 	}
 	testSlice("null", nil)
@@ -547,14 +436,9 @@ func TestDecodeLobTo(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
 
 			var val [8]byte
-			err := d.DecodeTo(&val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, d.DecodeTo(&val))
 
-			if !bytes.Equal(val[:], eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, bytes.Equal(val[:], eval), "expected %v, got %v", eval, val)
 		})
 	}
 	testArray("null", make([]byte, 8))
@@ -565,13 +449,9 @@ func TestDecodeStructTo(t *testing.T) {
 	test := func(str string, val, eval interface{}) {
 		t.Run(str, func(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
-			err := d.DecodeTo(val)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !reflect.DeepEqual(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			require.NoError(t, d.DecodeTo(val))
+
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -595,13 +475,9 @@ func TestDecodeListTo(t *testing.T) {
 	test := func(str string, val, eval interface{}) {
 		t.Run(str, func(t *testing.T) {
 			d := NewDecoder(NewReaderString(str))
-			err := d.DecodeTo(val)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !reflect.DeepEqual(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			require.NoError(t, d.DecodeTo(val))
+
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -628,9 +504,8 @@ func TestDecode(t *testing.T) {
 		t.Run(data, func(t *testing.T) {
 			d := NewDecoder(NewReaderString(data))
 			val, err := d.Decode()
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, err)
+
 			res := false
 			switch thisValue := val.(type) {
 			case *float64:
@@ -640,9 +515,7 @@ func TestDecode(t *testing.T) {
 			default:
 				res = reflect.DeepEqual(val, eval)
 			}
-			if !res {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.True(t, res, "expected %v, got %v", eval, val)
 		})
 	}
 
@@ -702,9 +575,9 @@ func TestDecodeLotsOfInts(t *testing.T) {
 	buf := bytes.Buffer{}
 	w := NewBinaryWriter(&buf)
 	for i := 0; i < 512; i++ {
-		w.WriteInt(1570737066801085)
+		assert.NoError(t, w.WriteInt(1570737066801085))
 	}
-	w.Finish()
+	assert.NoError(t, w.Finish())
 	bs := buf.Bytes()
 
 	// The binary reader wraps a bufio.Reader with an internal 4096-byte
@@ -719,12 +592,8 @@ func TestDecodeLotsOfInts(t *testing.T) {
 		if err == ErrNoInput {
 			break
 		}
-		if err != nil {
-			t.Fatal(err)
-		}
-		if val.(int64) != 1570737066801085 {
-			t.Fatalf("expected %v, got %v", 1570737066801085, val)
-		}
+		require.NoError(t, err)
+		require.Equal(t, int64(1570737066801085), val.(int64))
 	}
 }
 
@@ -737,14 +606,9 @@ func TestUnmarshalWithAnnotation(t *testing.T) {
 	test := func(str, testName string, eval foo) {
 		t.Run(testName, func(t *testing.T) {
 			var val foo
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if !reflect.DeepEqual(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -771,14 +635,9 @@ func TestUnmarshalContainersWithAnnotation(t *testing.T) {
 	test := func(str, testName string, eval interface{}) {
 		t.Run(testName, func(t *testing.T) {
 			var val foo
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if !reflect.DeepEqual(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}
 
@@ -805,14 +664,9 @@ func TestUnmarshalNestedStructsWithAnnotation(t *testing.T) {
 	test := func(str, testName string, eval interface{}) {
 		t.Run(testName, func(t *testing.T) {
 			var val topLevelStruct
-			err := UnmarshalString(str, &val)
-			if err != nil {
-				t.Fatal(err)
-			}
+			require.NoError(t, UnmarshalString(str, &val))
 
-			if !reflect.DeepEqual(val, eval) {
-				t.Errorf("expected %v, got %v", eval, val)
-			}
+			assert.Equal(t, eval, val)
 		})
 	}