You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2023/05/31 14:59:18 UTC

[avro] branch master updated: AVRO-3766: [Rust] Print friendlier errors when test cases fail (#2263)

This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/master by this push:
     new 57f1d5278 AVRO-3766: [Rust] Print friendlier errors when test cases fail (#2263)
57f1d5278 is described below

commit 57f1d5278427e2b095ec8d539d32bb9b309f9e07
Author: Martin Grigorov <ma...@users.noreply.github.com>
AuthorDate: Wed May 31 17:59:10 2023 +0300

    AVRO-3766: [Rust] Print friendlier errors when test cases fail (#2263)
    
    https://bluxte.net/musings/2023/01/08/improving_failure_messages_rust_tests/
    
    Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
---
 lang/rust/Cargo.lock                               |   1 +
 lang/rust/avro/examples/benchmark.rs               |   5 +-
 lang/rust/avro/examples/generate_interop_data.rs   |   5 +-
 lang/rust/avro/examples/test_interop_data.rs       |   3 +-
 lang/rust/avro/src/codec.rs                        |  35 +-
 lang/rust/avro/src/de.rs                           |  77 +--
 lang/rust/avro/src/decimal.rs                      |  13 +-
 lang/rust/avro/src/decode.rs                       |  75 ++-
 lang/rust/avro/src/reader.rs                       |  93 ++--
 lang/rust/avro/src/schema.rs                       | 533 +++++++++++++--------
 lang/rust/avro/src/schema_compatibility.rs         |  58 ++-
 lang/rust/avro/src/ser.rs                          |  55 ++-
 lang/rust/avro/src/types.rs                        | 234 +++++----
 lang/rust/avro/src/util.rs                         |   7 +-
 lang/rust/avro/src/writer.rs                       | 204 ++++----
 lang/rust/avro/tests/append_to_existing.rs         |   5 +-
 lang/rust/avro/tests/io.rs                         |  95 ++--
 lang/rust/avro/tests/schema.rs                     | 164 ++++---
 lang/rust/avro/tests/shared.rs                     |   4 +-
 .../rust/avro/tests/to_from_avro_datum_schemata.rs |  24 +-
 lang/rust/avro_test_helper/Cargo.toml              |   1 +
 lang/rust/avro_test_helper/src/lib.rs              |  16 +
 22 files changed, 1028 insertions(+), 679 deletions(-)

diff --git a/lang/rust/Cargo.lock b/lang/rust/Cargo.lock
index 1acf9bcd8..7097a7ec3 100644
--- a/lang/rust/Cargo.lock
+++ b/lang/rust/Cargo.lock
@@ -98,6 +98,7 @@ dependencies = [
 name = "apache-avro-test-helper"
 version = "0.15.0"
 dependencies = [
+ "anyhow",
  "color-backtrace",
  "ctor 0.2.0",
  "env_logger",
diff --git a/lang/rust/avro/examples/benchmark.rs b/lang/rust/avro/examples/benchmark.rs
index 4cf0f1365..c3eac4313 100644
--- a/lang/rust/avro/examples/benchmark.rs
+++ b/lang/rust/avro/examples/benchmark.rs
@@ -20,6 +20,7 @@ use apache_avro::{
     types::{Record, Value},
     Reader, Writer,
 };
+use apache_avro_test_helper::TestResult;
 use std::{
     io::{BufReader, BufWriter},
     time::{Duration, Instant},
@@ -45,7 +46,7 @@ fn benchmark(
     big_or_small: &str,
     count: usize,
     runs: usize,
-) -> anyhow::Result<()> {
+) -> TestResult {
     let mut records = Vec::new();
     for __ in 0..count {
         records.push(record.clone());
@@ -100,7 +101,7 @@ fn benchmark(
     Ok(())
 }
 
-fn main() -> anyhow::Result<()> {
+fn main() -> TestResult {
     let raw_small_schema = r#"
         {"namespace": "test", "type": "record", "name": "Test", "fields": [{"type": {"type": "string"}, "name": "field"}]}
     "#;
diff --git a/lang/rust/avro/examples/generate_interop_data.rs b/lang/rust/avro/examples/generate_interop_data.rs
index 72b4d10b2..35a6dc7c0 100644
--- a/lang/rust/avro/examples/generate_interop_data.rs
+++ b/lang/rust/avro/examples/generate_interop_data.rs
@@ -20,6 +20,7 @@ use apache_avro::{
     types::{Record, Value},
     Codec, Writer,
 };
+use apache_avro_test_helper::TestResult;
 use std::{
     collections::HashMap,
     io::{BufWriter, Write},
@@ -74,7 +75,7 @@ fn create_datum(schema: &Schema) -> Record {
     datum
 }
 
-fn main() -> anyhow::Result<()> {
+fn main() -> TestResult {
     let schema_str = std::fs::read_to_string("../../share/test/schemas/interop.avsc")
         .expect("Unable to read the interop Avro schema");
     let schema = Schema::parse_str(schema_str.as_str())?;
@@ -104,7 +105,7 @@ fn main() -> anyhow::Result<()> {
     Ok(())
 }
 
-fn write_user_metadata<W: Write>(writer: &mut Writer<BufWriter<W>>) -> anyhow::Result<()> {
+fn write_user_metadata<W: Write>(writer: &mut Writer<BufWriter<W>>) -> TestResult {
     writer.add_user_metadata("user_metadata".to_string(), b"someByteArray")?;
 
     Ok(())
diff --git a/lang/rust/avro/examples/test_interop_data.rs b/lang/rust/avro/examples/test_interop_data.rs
index 611c0e192..736b1fd7d 100644
--- a/lang/rust/avro/examples/test_interop_data.rs
+++ b/lang/rust/avro/examples/test_interop_data.rs
@@ -16,13 +16,14 @@
 // under the License.
 
 use apache_avro::Reader;
+use apache_avro_test_helper::TestResult;
 use std::{
     collections::HashMap,
     ffi::OsStr,
     io::{BufReader, Read},
 };
 
-fn main() -> anyhow::Result<()> {
+fn main() -> TestResult {
     let mut expected_user_metadata: HashMap<String, Vec<u8>> = HashMap::new();
     expected_user_metadata.insert("user_metadata".to_string(), b"someByteArray".to_vec());
 
diff --git a/lang/rust/avro/src/codec.rs b/lang/rust/avro/src/codec.rs
index 0866ff62d..c34da0bfc 100644
--- a/lang/rust/avro/src/codec.rs
+++ b/lang/rust/avro/src/codec.rs
@@ -186,55 +186,58 @@ impl Codec {
 mod tests {
     use super::*;
     use pretty_assertions::{assert_eq, assert_ne};
+    use apache_avro_test_helper::TestResult;
 
     const INPUT: &[u8] = b"theanswertolifetheuniverseandeverythingis42theanswertolifetheuniverseandeverythingis4theanswertolifetheuniverseandeverythingis2";
 
     #[test]
-    fn null_compress_and_decompress() {
+    fn null_compress_and_decompress() -> TestResult {
         let codec = Codec::Null;
         let mut stream = INPUT.to_vec();
-        codec.compress(&mut stream).unwrap();
+        codec.compress(&mut stream)?;
         assert_eq!(INPUT, stream.as_slice());
-        codec.decompress(&mut stream).unwrap();
+        codec.decompress(&mut stream)?;
         assert_eq!(INPUT, stream.as_slice());
+        Ok(())
     }
 
     #[test]
-    fn deflate_compress_and_decompress() {
-        compress_and_decompress(Codec::Deflate);
+    fn deflate_compress_and_decompress()-> TestResult  {
+        compress_and_decompress(Codec::Deflate)
     }
 
     #[cfg(feature = "snappy")]
     #[test]
-    fn snappy_compress_and_decompress() {
-        compress_and_decompress(Codec::Snappy);
+    fn snappy_compress_and_decompress()-> TestResult  {
+        compress_and_decompress(Codec::Snappy)
     }
 
     #[cfg(feature = "zstandard")]
     #[test]
-    fn zstd_compress_and_decompress() {
-        compress_and_decompress(Codec::Zstandard);
+    fn zstd_compress_and_decompress()-> TestResult  {
+        compress_and_decompress(Codec::Zstandard)
     }
 
     #[cfg(feature = "bzip")]
     #[test]
-    fn bzip_compress_and_decompress() {
-        compress_and_decompress(Codec::Bzip2);
+    fn bzip_compress_and_decompress()-> TestResult  {
+        compress_and_decompress(Codec::Bzip2)
     }
 
     #[cfg(feature = "xz")]
     #[test]
-    fn xz_compress_and_decompress() {
-        compress_and_decompress(Codec::Xz);
+    fn xz_compress_and_decompress()-> TestResult  {
+        compress_and_decompress(Codec::Xz)
     }
 
-    fn compress_and_decompress(codec: Codec) {
+    fn compress_and_decompress(codec: Codec) -> TestResult {
         let mut stream = INPUT.to_vec();
-        codec.compress(&mut stream).unwrap();
+        codec.compress(&mut stream)?;
         assert_ne!(INPUT, stream.as_slice());
         assert!(INPUT.len() > stream.len());
-        codec.decompress(&mut stream).unwrap();
+        codec.decompress(&mut stream)?;
         assert_eq!(INPUT, stream.as_slice());
+        Ok(())
     }
 
     #[test]
diff --git a/lang/rust/avro/src/de.rs b/lang/rust/avro/src/de.rs
index a1b52e6c5..a2e7a0e52 100644
--- a/lang/rust/avro/src/de.rs
+++ b/lang/rust/avro/src/de.rs
@@ -654,6 +654,8 @@ mod tests {
     use std::sync::atomic::Ordering;
     use uuid::Uuid;
 
+    use apache_avro_test_helper::TestResult;
+
     use super::*;
 
     #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
@@ -749,7 +751,7 @@ mod tests {
     }
 
     #[test]
-    fn test_from_value() {
+    fn test_from_value() -> TestResult {
         let test = Value::Record(vec![
             ("a".to_owned(), Value::Long(27)),
             ("b".to_owned(), Value::String("foo".to_owned())),
@@ -758,7 +760,7 @@ mod tests {
             a: 27,
             b: "foo".to_owned(),
         };
-        let final_value: Test = from_value(&test).unwrap();
+        let final_value: Test = from_value(&test)?;
         assert_eq!(final_value, expected);
 
         let test_inner = Value::Record(vec![
@@ -773,18 +775,20 @@ mod tests {
         ]);
 
         let expected_inner = TestInner { a: expected, b: 35 };
-        let final_value: TestInner = from_value(&test_inner).unwrap();
-        assert_eq!(final_value, expected_inner)
+        let final_value: TestInner = from_value(&test_inner)?;
+        assert_eq!(final_value, expected_inner);
+
+        Ok(())
     }
 
     #[test]
-    fn test_from_value_unit_enum() {
+    fn test_from_value_unit_enum() -> TestResult {
         let expected = TestUnitExternalEnum {
             a: UnitExternalEnum::Val1,
         };
 
         let test = Value::Record(vec![("a".to_owned(), Value::Enum(0, "Val1".to_owned()))]);
-        let final_value: TestUnitExternalEnum = from_value(&test).unwrap();
+        let final_value: TestUnitExternalEnum = from_value(&test)?;
         assert_eq!(
             final_value, expected,
             "Error deserializing unit external enum"
@@ -798,7 +802,7 @@ mod tests {
             "a".to_owned(),
             Value::Record(vec![("t".to_owned(), Value::String("Val1".to_owned()))]),
         )]);
-        let final_value: TestUnitInternalEnum = from_value(&test).unwrap();
+        let final_value: TestUnitInternalEnum = from_value(&test)?;
         assert_eq!(
             final_value, expected,
             "Error deserializing unit internal enum"
@@ -811,7 +815,7 @@ mod tests {
             "a".to_owned(),
             Value::Record(vec![("t".to_owned(), Value::String("Val1".to_owned()))]),
         )]);
-        let final_value: TestUnitAdjacentEnum = from_value(&test).unwrap();
+        let final_value: TestUnitAdjacentEnum = from_value(&test)?;
         assert_eq!(
             final_value, expected,
             "Error deserializing unit adjacent enum"
@@ -821,15 +825,16 @@ mod tests {
         };
 
         let test = Value::Record(vec![("a".to_owned(), Value::Null)]);
-        let final_value: TestUnitUntaggedEnum = from_value(&test).unwrap();
+        let final_value: TestUnitUntaggedEnum = from_value(&test)?;
         assert_eq!(
             final_value, expected,
             "Error deserializing unit untagged enum"
         );
+        Ok(())
     }
 
     #[test]
-    fn avro_3645_3646_test_from_value_enum() {
+    fn avro_3645_3646_test_from_value_enum() -> TestResult {
         #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
         struct TestNullExternalEnum {
             a: NullExternalEnum,
@@ -901,13 +906,15 @@ mod tests {
         ];
 
         for (expected, test) in data.iter() {
-            let actual: TestNullExternalEnum = from_value(test).unwrap();
+            let actual: TestNullExternalEnum = from_value(test)?;
             assert_eq!(actual, *expected);
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_from_value_single_value_enum() {
+    fn test_from_value_single_value_enum() -> TestResult {
         let expected = TestSingleValueExternalEnum {
             a: SingleValueExternalEnum::Double(64.0),
         };
@@ -922,15 +929,17 @@ mod tests {
                 ),
             ]),
         )]);
-        let final_value: TestSingleValueExternalEnum = from_value(&test).unwrap();
+        let final_value: TestSingleValueExternalEnum = from_value(&test)?;
         assert_eq!(
             final_value, expected,
             "Error deserializing single value external enum(union)"
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_from_value_struct_enum() {
+    fn test_from_value_struct_enum() -> TestResult {
         let expected = TestStructExternalEnum {
             a: StructExternalEnum::Val1 { x: 1.0, y: 2.0 },
         };
@@ -951,15 +960,17 @@ mod tests {
                 ),
             ]),
         )]);
-        let final_value: TestStructExternalEnum = from_value(&test).unwrap();
+        let final_value: TestStructExternalEnum = from_value(&test)?;
         assert_eq!(
             final_value, expected,
             "error deserializing struct external enum(union)"
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3692_from_value_struct_flatten() {
+    fn test_avro_3692_from_value_struct_flatten() -> TestResult {
         #[derive(Deserialize, PartialEq, Debug)]
         struct S1 {
             f1: String,
@@ -981,12 +992,14 @@ mod tests {
             ("f1".to_owned(), "Hello".into()),
             ("f2".to_owned(), "World".into()),
         ]);
-        let final_value: S1 = from_value(&test).unwrap();
+        let final_value: S1 = from_value(&test)?;
         assert_eq!(final_value, expected);
+
+        Ok(())
     }
 
     #[test]
-    fn test_from_value_tuple_enum() {
+    fn test_from_value_tuple_enum() -> TestResult {
         let expected = TestTupleExternalEnum {
             a: TupleExternalEnum::Val1(1.0, 2.0),
         };
@@ -1004,17 +1017,17 @@ mod tests {
                 ),
             ]),
         )]);
-        let final_value: TestTupleExternalEnum = from_value(&test).unwrap();
+        let final_value: TestTupleExternalEnum = from_value(&test)?;
         assert_eq!(
             final_value, expected,
             "error serializing tuple external enum(union)"
         );
-    }
 
-    type TestResult<T> = anyhow::Result<T, Box<dyn std::error::Error>>;
+        Ok(())
+    }
 
     #[test]
-    fn test_date() -> TestResult<()> {
+    fn test_date() -> TestResult {
         let raw_value = 1;
         let value = Value::Date(raw_value);
         let result = crate::from_value::<i32>(&value)?;
@@ -1023,7 +1036,7 @@ mod tests {
     }
 
     #[test]
-    fn test_time_millis() -> TestResult<()> {
+    fn test_time_millis() -> TestResult {
         let raw_value = 1;
         let value = Value::TimeMillis(raw_value);
         let result = crate::from_value::<i32>(&value)?;
@@ -1032,7 +1045,7 @@ mod tests {
     }
 
     #[test]
-    fn test_time_micros() -> TestResult<()> {
+    fn test_time_micros() -> TestResult {
         let raw_value = 1;
         let value = Value::TimeMicros(raw_value);
         let result = crate::from_value::<i64>(&value)?;
@@ -1041,7 +1054,7 @@ mod tests {
     }
 
     #[test]
-    fn test_timestamp_millis() -> TestResult<()> {
+    fn test_timestamp_millis() -> TestResult {
         let raw_value = 1;
         let value = Value::TimestampMillis(raw_value);
         let result = crate::from_value::<i64>(&value)?;
@@ -1050,7 +1063,7 @@ mod tests {
     }
 
     #[test]
-    fn test_timestamp_micros() -> TestResult<()> {
+    fn test_timestamp_micros() -> TestResult {
         let raw_value = 1;
         let value = Value::TimestampMicros(raw_value);
         let result = crate::from_value::<i64>(&value)?;
@@ -1059,16 +1072,16 @@ mod tests {
     }
 
     #[test]
-    fn test_from_value_uuid_str() -> TestResult<()> {
+    fn test_from_value_uuid_str() -> TestResult {
         let raw_value = "9ec535ff-3e2a-45bd-91d3-0a01321b5a49";
-        let value = Value::Uuid(Uuid::parse_str(raw_value).unwrap());
+        let value = Value::Uuid(Uuid::parse_str(raw_value)?);
         let result = crate::from_value::<Uuid>(&value)?;
         assert_eq!(result.to_string(), raw_value);
         Ok(())
     }
 
     #[test]
-    fn test_from_value_uuid_slice() -> TestResult<()> {
+    fn test_from_value_uuid_slice() -> TestResult {
         let raw_value = &[4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87];
         let value = Value::Uuid(Uuid::from_slice(raw_value)?);
         let result = crate::from_value::<Uuid>(&value)?;
@@ -1077,7 +1090,7 @@ mod tests {
     }
 
     #[test]
-    fn test_from_value_with_union() -> TestResult<()> {
+    fn test_from_value_with_union() -> TestResult {
         // AVRO-3232 test for deserialize_any on missing fields on the destination struct:
         // Error: DeserializeValue("Unsupported union")
         // Error: DeserializeValue("incorrect value of type: String")
@@ -1227,7 +1240,7 @@ mod tests {
     }
 
     #[test]
-    fn avro_3747_human_readable_false() -> TestResult<()> {
+    fn avro_3747_human_readable_false() -> TestResult {
         use serde::de::Deserializer as SerdeDeserializer;
 
         let is_human_readable = false;
@@ -1241,7 +1254,7 @@ mod tests {
     }
 
     #[test]
-    fn avro_3747_human_readable_true() -> TestResult<()> {
+    fn avro_3747_human_readable_true() -> TestResult {
         use serde::de::Deserializer as SerdeDeserializer;
 
         crate::util::SERDE_HUMAN_READABLE.store(true, Ordering::Release);
diff --git a/lang/rust/avro/src/decimal.rs b/lang/rust/avro/src/decimal.rs
index e67430384..4373205df 100644
--- a/lang/rust/avro/src/decimal.rs
+++ b/lang/rust/avro/src/decimal.rs
@@ -104,22 +104,27 @@ mod tests {
     use super::*;
     use pretty_assertions::assert_eq;
     use std::convert::TryFrom;
+    use apache_avro_test_helper::TestResult;
 
     #[test]
-    fn test_decimal_from_bytes_from_ref_decimal() {
+    fn test_decimal_from_bytes_from_ref_decimal() -> TestResult {
         let input = vec![1, 24];
         let d = Decimal::from(&input);
 
-        let output = <Vec<u8>>::try_from(&d).unwrap();
+        let output = <Vec<u8>>::try_from(&d)?;
         assert_eq!(output, input);
+
+        Ok(())
     }
 
     #[test]
-    fn test_decimal_from_bytes_from_owned_decimal() {
+    fn test_decimal_from_bytes_from_owned_decimal() -> TestResult {
         let input = vec![1, 24];
         let d = Decimal::from(&input);
 
-        let output = <Vec<u8>>::try_from(d).unwrap();
+        let output = <Vec<u8>>::try_from(d)?;
         assert_eq!(output, input);
+
+        Ok(())
     }
 }
diff --git a/lang/rust/avro/src/decode.rs b/lang/rust/avro/src/decode.rs
index 31b76243a..39efefced 100644
--- a/lang/rust/avro/src/decode.rs
+++ b/lang/rust/avro/src/decode.rs
@@ -305,47 +305,56 @@ mod tests {
     };
     use pretty_assertions::assert_eq;
     use std::collections::HashMap;
+    use apache_avro_test_helper::TestResult;
 
     #[test]
-    fn test_decode_array_without_size() {
+    fn test_decode_array_without_size() -> TestResult {
         let mut input: &[u8] = &[6, 2, 4, 6, 0];
         let result = decode(&Schema::Array(Box::new(Schema::Int)), &mut input);
-        assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result.unwrap());
+        assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result?);
+
+        Ok(())
     }
 
     #[test]
-    fn test_decode_array_with_size() {
+    fn test_decode_array_with_size() -> TestResult {
         let mut input: &[u8] = &[5, 6, 2, 4, 6, 0];
         let result = decode(&Schema::Array(Box::new(Schema::Int)), &mut input);
-        assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result.unwrap());
+        assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result?);
+
+        Ok(())
     }
 
     #[test]
-    fn test_decode_map_without_size() {
+    fn test_decode_map_without_size() -> TestResult {
         let mut input: &[u8] = &[0x02, 0x08, 0x74, 0x65, 0x73, 0x74, 0x02, 0x00];
         let result = decode(&Schema::Map(Box::new(Schema::Int)), &mut input);
         let mut expected = HashMap::new();
         expected.insert(String::from("test"), Int(1));
-        assert_eq!(Map(expected), result.unwrap());
+        assert_eq!(Map(expected), result?);
+
+        Ok(())
     }
 
     #[test]
-    fn test_decode_map_with_size() {
+    fn test_decode_map_with_size() -> TestResult {
         let mut input: &[u8] = &[0x01, 0x0C, 0x08, 0x74, 0x65, 0x73, 0x74, 0x02, 0x00];
         let result = decode(&Schema::Map(Box::new(Schema::Int)), &mut input);
         let mut expected = HashMap::new();
         expected.insert(String::from("test"), Int(1));
-        assert_eq!(Map(expected), result.unwrap());
+        assert_eq!(Map(expected), result?);
+
+        Ok(())
     }
 
     #[test]
-    fn test_negative_decimal_value() {
+    fn test_negative_decimal_value() -> TestResult {
         use crate::{encode::encode, schema::Name};
         use num_bigint::ToBigInt;
         let inner = Box::new(Schema::Fixed(FixedSchema {
             size: 2,
             doc: None,
-            name: Name::new("decimal").unwrap(),
+            name: Name::new("decimal")?,
             aliases: None,
             attributes: Default::default(),
         }));
@@ -361,17 +370,19 @@ mod tests {
         encode(&value, &schema, &mut buffer).expect(&success(&value, &schema));
 
         let mut bytes = &buffer[..];
-        let result = decode(&schema, &mut bytes).unwrap();
+        let result = decode(&schema, &mut bytes)?;
         assert_eq!(result, value);
+
+        Ok(())
     }
 
     #[test]
-    fn test_decode_decimal_with_bigger_than_necessary_size() {
+    fn test_decode_decimal_with_bigger_than_necessary_size() -> TestResult {
         use crate::{encode::encode, schema::Name};
         use num_bigint::ToBigInt;
         let inner = Box::new(Schema::Fixed(FixedSchema {
             size: 13,
-            name: Name::new("decimal").unwrap(),
+            name: Name::new("decimal")?,
             aliases: None,
             doc: None,
             attributes: Default::default(),
@@ -388,12 +399,14 @@ mod tests {
 
         encode(&value, &schema, &mut buffer).expect(&success(&value, &schema));
         let mut bytes: &[u8] = &buffer[..];
-        let result = decode(&schema, &mut bytes).unwrap();
+        let result = decode(&schema, &mut bytes)?;
         assert_eq!(result, value);
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3448_recursive_definition_decode_union() {
+    fn test_avro_3448_recursive_definition_decode_union() -> TestResult {
         // if encoding fails in this test check the corresponding test in encode
         let schema = Schema::parse_str(
             r#"
@@ -419,7 +432,7 @@ mod tests {
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -453,10 +466,12 @@ mod tests {
                 &schema
             ))
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3448_recursive_definition_decode_array() {
+    fn test_avro_3448_recursive_definition_decode_array() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -484,7 +499,7 @@ mod tests {
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -501,11 +516,13 @@ mod tests {
                 "Failed to decode using recursive definitions with schema:\n {:?}\n",
                 &schema
             ))
-        )
+        );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3448_recursive_definition_decode_map() {
+    fn test_avro_3448_recursive_definition_decode_map() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -533,7 +550,7 @@ mod tests {
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -553,11 +570,13 @@ mod tests {
                 "Failed to decode using recursive definitions with schema:\n {:?}\n",
                 &schema
             ))
-        )
+        );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3448_proper_multi_level_decoding_middle_namespace() {
+    fn test_avro_3448_proper_multi_level_decoding_middle_namespace() -> TestResult {
         // if encoding fails in this test check the corresponding test in encode
         let schema = r#"
         {
@@ -601,7 +620,7 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]);
         let middle_record_variation_1 = Value::Record(vec![(
             "middle_field_1".into(),
@@ -668,10 +687,12 @@ mod tests {
                 &schema
             ))
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3448_proper_multi_level_decoding_inner_namespace() {
+    fn test_avro_3448_proper_multi_level_decoding_inner_namespace() -> TestResult {
         // if encoding fails in this test check the corresponding test in encode
         let schema = r#"
         {
@@ -716,7 +737,7 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]);
         let middle_record_variation_1 = Value::Record(vec![(
             "middle_field_1".into(),
@@ -783,5 +804,7 @@ mod tests {
                 &schema
             ))
         );
+
+        Ok(())
     }
 }
diff --git a/lang/rust/avro/src/reader.rs b/lang/rust/avro/src/reader.rs
index bdd318861..f83c30f3f 100644
--- a/lang/rust/avro/src/reader.rs
+++ b/lang/rust/avro/src/reader.rs
@@ -532,6 +532,7 @@ mod tests {
     use pretty_assertions::assert_eq;
     use serde::Deserialize;
     use std::io::Cursor;
+    use apache_avro_test_helper::TestResult;
 
     const SCHEMA: &str = r#"
     {
@@ -569,8 +570,8 @@ mod tests {
     ];
 
     #[test]
-    fn test_from_avro_datum() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_from_avro_datum() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut encoded: &'static [u8] = &[54, 6, 102, 111, 111];
 
         let mut record = Record::new(&schema).unwrap();
@@ -579,13 +580,15 @@ mod tests {
         let expected = record.into();
 
         assert_eq!(
-            from_avro_datum(&schema, &mut encoded, None).unwrap(),
+            from_avro_datum(&schema, &mut encoded, None)?,
             expected
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_from_avro_datum_with_union_to_struct() {
+    fn test_from_avro_datum_with_union_to_struct() -> TestResult {
         const TEST_RECORD_SCHEMA_3240: &str = r#"
     {
       "type": "record",
@@ -628,7 +631,7 @@ mod tests {
             a_nullable_string: Option<String>,
         }
 
-        let schema = Schema::parse_str(TEST_RECORD_SCHEMA_3240).unwrap();
+        let schema = Schema::parse_str(TEST_RECORD_SCHEMA_3240)?;
         let mut encoded: &'static [u8] = &[54, 6, 102, 111, 111];
 
         let expected_record: TestRecord3240 = TestRecord3240 {
@@ -638,32 +641,36 @@ mod tests {
             a_nullable_string: None,
         };
 
-        let avro_datum = from_avro_datum(&schema, &mut encoded, None).unwrap();
+        let avro_datum = from_avro_datum(&schema, &mut encoded, None)?;
         let parsed_record: TestRecord3240 = match &avro_datum {
-            Value::Record(_) => from_value::<TestRecord3240>(&avro_datum).unwrap(),
+            Value::Record(_) => from_value::<TestRecord3240>(&avro_datum)?,
             unexpected => {
                 panic!("could not map avro data to struct, found unexpected: {unexpected:?}")
             }
         };
 
         assert_eq!(parsed_record, expected_record);
+
+        Ok(())
     }
 
     #[test]
-    fn test_null_union() {
-        let schema = Schema::parse_str(UNION_SCHEMA).unwrap();
+    fn test_null_union() -> TestResult {
+        let schema = Schema::parse_str(UNION_SCHEMA)?;
         let mut encoded: &'static [u8] = &[2, 0];
 
         assert_eq!(
-            from_avro_datum(&schema, &mut encoded, None).unwrap(),
+            from_avro_datum(&schema, &mut encoded, None)?,
             Value::Union(1, Box::new(Value::Long(0)))
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_reader_iterator() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
-        let reader = Reader::with_schema(&schema, ENCODED).unwrap();
+    fn test_reader_iterator() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
+        let reader = Reader::with_schema(&schema, ENCODED)?;
 
         let mut record1 = Record::new(&schema).unwrap();
         record1.put("a", 27i64);
@@ -676,20 +683,24 @@ mod tests {
         let expected = vec![record1.into(), record2.into()];
 
         for (i, value) in reader.enumerate() {
-            assert_eq!(value.unwrap(), expected[i]);
+            assert_eq!(value?, expected[i]);
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_reader_invalid_header() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_reader_invalid_header() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let invalid = ENCODED.iter().copied().skip(1).collect::<Vec<u8>>();
         assert!(Reader::with_schema(&schema, &invalid[..]).is_err());
+
+        Ok(())
     }
 
     #[test]
-    fn test_reader_invalid_block() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_reader_invalid_block() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let invalid = ENCODED
             .iter()
             .copied()
@@ -699,32 +710,38 @@ mod tests {
             .into_iter()
             .rev()
             .collect::<Vec<u8>>();
-        let reader = Reader::with_schema(&schema, &invalid[..]).unwrap();
+        let reader = Reader::with_schema(&schema, &invalid[..])?;
         for value in reader {
             assert!(value.is_err());
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_reader_empty_buffer() {
+    fn test_reader_empty_buffer() -> TestResult {
         let empty = Cursor::new(Vec::new());
         assert!(Reader::new(empty).is_err());
+
+        Ok(())
     }
 
     #[test]
-    fn test_reader_only_header() {
+    fn test_reader_only_header() -> TestResult {
         let invalid = ENCODED.iter().copied().take(165).collect::<Vec<u8>>();
-        let reader = Reader::new(&invalid[..]).unwrap();
+        let reader = Reader::new(&invalid[..])?;
         for value in reader {
             assert!(value.is_err());
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3405_read_user_metadata_success() {
+    fn test_avro_3405_read_user_metadata_success() -> TestResult {
         use crate::writer::Writer;
 
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
         let mut user_meta_data: HashMap<String, Vec<u8>> = HashMap::new();
@@ -736,20 +753,22 @@ mod tests {
         user_meta_data.insert("vecKey".to_string(), vec![1, 2, 3]);
 
         for (k, v) in user_meta_data.iter() {
-            writer.add_user_metadata(k.to_string(), v).unwrap();
+            writer.add_user_metadata(k.to_string(), v)?;
         }
 
         let mut record = Record::new(&schema).unwrap();
         record.put("a", 27i64);
         record.put("b", "foo");
 
-        writer.append(record.clone()).unwrap();
-        writer.append(record.clone()).unwrap();
-        writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        writer.append(record.clone())?;
+        writer.append(record.clone())?;
+        writer.flush()?;
+        let result = writer.into_inner()?;
 
-        let reader = Reader::new(&result[..]).unwrap();
+        let reader = Reader::new(&result[..])?;
         assert_eq!(reader.user_metadata(), &user_meta_data);
+
+        Ok(())
     }
 
     #[derive(Deserialize, Clone, PartialEq, Debug)]
@@ -833,7 +852,7 @@ mod tests {
     }
 
     #[test]
-    fn test_avro_3507_single_object_reader() {
+    fn test_avro_3507_single_object_reader() -> TestResult {
         let obj = TestSingleObjectReader {
             a: 42,
             b: 3.33,
@@ -860,10 +879,12 @@ mod tests {
             .expect("Should read");
         let expected_value: Value = obj.into();
         assert_eq!(expected_value, val);
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3642_test_single_object_reader_incomplete_reads() {
+    fn avro_3642_test_single_object_reader_incomplete_reads() -> TestResult {
         let obj = TestSingleObjectReader {
             a: 42,
             b: 3.33,
@@ -892,10 +913,12 @@ mod tests {
             .expect("Should read");
         let expected_value: Value = obj.into();
         assert_eq!(expected_value, val);
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3507_reader_parity() {
+    fn test_avro_3507_reader_parity() -> TestResult {
         let obj = TestSingleObjectReader {
             a: 42,
             b: 3.33,
@@ -935,7 +958,9 @@ mod tests {
         let expected_value: Value = obj.clone().into();
         assert_eq!(obj, read_obj1);
         assert_eq!(obj, read_obj2);
-        assert_eq!(val, expected_value)
+        assert_eq!(val, expected_value);
+
+        Ok(())
     }
 
     #[cfg(not(feature = "snappy"))]
diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index 629647abc..907a06222 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -276,12 +276,12 @@ impl Name {
     /// use apache_avro::schema::Name;
     ///
     /// assert_eq!(
-    /// Name::new("some_name").unwrap().fully_qualified_name(&Some("some_namespace".into())),
-    /// Name::new("some_namespace.some_name").unwrap()
+    /// Name::new("some_name")?.fully_qualified_name(&Some("some_namespace".into())),
+    /// Name::new("some_namespace.some_name")?
     /// );
     /// assert_eq!(
-    /// Name::new("some_namespace.some_name").unwrap().fully_qualified_name(&Some("other_namespace".into())),
-    /// Name::new("some_namespace.some_name").unwrap()
+    /// Name::new("some_namespace.some_name")?.fully_qualified_name(&Some("other_namespace".into())),
+    /// Name::new("some_namespace.some_name")?
     /// );
     /// ```
     pub fn fully_qualified_name(&self, enclosing_namespace: &Namespace) -> Name {
@@ -840,7 +840,7 @@ impl Schema {
     /// during parsing.
     ///
     /// If two of the input schemas have the same fullname, an Error will be returned.
-    pub fn parse_list(input: &[&str]) -> Result<Vec<Schema>, Error> {
+    pub fn parse_list(input: &[&str]) -> AvroResult<Vec<Schema>> {
         let mut input_schemas: HashMap<Name, Value> = HashMap::with_capacity(input.len());
         let mut input_order: Vec<Name> = Vec::with_capacity(input.len());
         for js in input {
@@ -2073,6 +2073,7 @@ mod tests {
     use super::*;
     use pretty_assertions::assert_eq;
     use serde_json::json;
+    use apache_avro_test_helper::TestResult;
 
     #[test]
     fn test_invalid_schema() {
@@ -2080,31 +2081,35 @@ mod tests {
     }
 
     #[test]
-    fn test_primitive_schema() {
-        assert_eq!(Schema::Null, Schema::parse_str("\"null\"").unwrap());
-        assert_eq!(Schema::Int, Schema::parse_str("\"int\"").unwrap());
-        assert_eq!(Schema::Double, Schema::parse_str("\"double\"").unwrap());
+    fn test_primitive_schema() -> TestResult {
+        assert_eq!(Schema::Null, Schema::parse_str("\"null\"")?);
+        assert_eq!(Schema::Int, Schema::parse_str("\"int\"")?);
+        assert_eq!(Schema::Double, Schema::parse_str("\"double\"")?);
+        Ok(())
     }
 
     #[test]
-    fn test_array_schema() {
-        let schema = Schema::parse_str(r#"{"type": "array", "items": "string"}"#).unwrap();
+    fn test_array_schema() -> TestResult {
+        let schema = Schema::parse_str(r#"{"type": "array", "items": "string"}"#)?;
         assert_eq!(Schema::Array(Box::new(Schema::String)), schema);
+        Ok(())
     }
 
     #[test]
-    fn test_map_schema() {
-        let schema = Schema::parse_str(r#"{"type": "map", "values": "double"}"#).unwrap();
+    fn test_map_schema() -> TestResult {
+        let schema = Schema::parse_str(r#"{"type": "map", "values": "double"}"#)?;
         assert_eq!(Schema::Map(Box::new(Schema::Double)), schema);
+        Ok(())
     }
 
     #[test]
-    fn test_union_schema() {
-        let schema = Schema::parse_str(r#"["null", "int"]"#).unwrap();
+    fn test_union_schema() -> TestResult {
+        let schema = Schema::parse_str(r#"["null", "int"]"#)?;
         assert_eq!(
-            Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()),
+            Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?),
             schema
         );
+        Ok(())
     }
 
     #[test]
@@ -2114,10 +2119,10 @@ mod tests {
     }
 
     #[test]
-    fn test_multi_union_schema() {
+    fn test_multi_union_schema() -> TestResult {
         let schema = Schema::parse_str(r#"["null", "int", "float", "string", "bytes"]"#);
         assert!(schema.is_ok());
-        let schema = schema.unwrap();
+        let schema = schema?;
         assert_eq!(SchemaKind::from(&schema), SchemaKind::Union);
         let union_schema = match schema {
             Schema::Union(u) => u,
@@ -2140,11 +2145,12 @@ mod tests {
             SchemaKind::Bytes
         );
         assert_eq!(variants.next(), None);
+
+        Ok(())
     }
 
-    // AVRO-3621
     #[test]
-    fn test_avro_3621_nullable_record_field() {
+    fn test_avro_3621_nullable_record_field() -> TestResult {
         let nullable_record_field = RecordField {
             name: "next".to_string(),
             doc: None,
@@ -2160,7 +2166,7 @@ mod tests {
                         },
                     },
                 ])
-                .unwrap(),
+                ?,
             ),
             order: RecordFieldOrder::Ascending,
             position: 1,
@@ -2181,11 +2187,12 @@ mod tests {
         };
 
         assert!(!non_nullable_record_field.is_nullable());
+        Ok(())
     }
 
     // AVRO-3248
     #[test]
-    fn test_union_of_records() {
+    fn test_union_of_records() -> TestResult {
         use std::iter::FromIterator;
 
         // A and B are the same except the name.
@@ -2214,14 +2221,13 @@ mod tests {
             ]
         }"#;
 
-        let schema_c = Schema::parse_list(&[schema_str_a, schema_str_b, schema_str_c])
-            .unwrap()
+        let schema_c = Schema::parse_list(&[schema_str_a, schema_str_b, schema_str_c])?
             .last()
             .unwrap()
             .clone();
 
         let schema_c_expected = Schema::Record(RecordSchema {
-            name: Name::new("C").unwrap(),
+            name: Name::new("C")?,
             aliases: None,
             doc: None,
             fields: vec![RecordField {
@@ -2232,13 +2238,13 @@ mod tests {
                 schema: Schema::Union(
                     UnionSchema::new(vec![
                         Schema::Ref {
-                            name: Name::new("A").unwrap(),
+                            name: Name::new("A")?,
                         },
                         Schema::Ref {
-                            name: Name::new("B").unwrap(),
+                            name: Name::new("B")?,
                         },
                     ])
-                    .unwrap(),
+                    ?,
                 ),
                 order: RecordFieldOrder::Ignore,
                 position: 0,
@@ -2249,11 +2255,11 @@ mod tests {
         });
 
         assert_eq!(schema_c, schema_c_expected);
+        Ok(())
     }
 
-    // AVRO-3584 : recursion in type definitions
     #[test]
-    fn avro_3584_test_recursion_records() {
+    fn avro_3584_test_recursion_records() -> TestResult {
         // A and B are the same except the name.
         let schema_str_a = r#"{
             "name": "A",
@@ -2267,7 +2273,7 @@ mod tests {
             "fields": [ {"name": "field_one", "type": "A"} ]
         }"#;
 
-        let list = Schema::parse_list(&[schema_str_a, schema_str_b]).unwrap();
+        let list = Schema::parse_list(&[schema_str_a, schema_str_b])?;
 
         let schema_a = list.first().unwrap().clone();
 
@@ -2276,17 +2282,18 @@ mod tests {
                 let f1 = fields.get(0);
 
                 let ref_schema = Schema::Ref {
-                    name: Name::new("B").unwrap(),
+                    name: Name::new("B")?,
                 };
                 assert_eq!(ref_schema, f1.unwrap().schema);
             }
             _ => panic!("Expected a record schema!"),
         }
+
+        Ok(())
     }
 
-    // AVRO-3248
     #[test]
-    fn test_nullable_record() {
+    fn test_avro_3248_nullable_record() -> TestResult {
         use std::iter::FromIterator;
 
         let schema_str_a = r#"{
@@ -2306,14 +2313,13 @@ mod tests {
             ]
         }"#;
 
-        let schema_option_a = Schema::parse_list(&[schema_str_a, schema_str_option_a])
-            .unwrap()
+        let schema_option_a = Schema::parse_list(&[schema_str_a, schema_str_option_a])?
             .last()
             .unwrap()
             .clone();
 
         let schema_option_a_expected = Schema::Record(RecordSchema {
-            name: Name::new("OptionA").unwrap(),
+            name: Name::new("OptionA")?,
             aliases: None,
             doc: None,
             fields: vec![RecordField {
@@ -2325,10 +2331,10 @@ mod tests {
                     UnionSchema::new(vec![
                         Schema::Null,
                         Schema::Ref {
-                            name: Name::new("A").unwrap(),
+                            name: Name::new("A")?,
                         },
                     ])
-                    .unwrap(),
+                    ?,
                 ),
                 order: RecordFieldOrder::Ignore,
                 position: 0,
@@ -2339,10 +2345,12 @@ mod tests {
         });
 
         assert_eq!(schema_option_a, schema_option_a_expected);
+
+        Ok(())
     }
 
     #[test]
-    fn test_record_schema() {
+    fn test_record_schema() -> TestResult {
         let parsed = Schema::parse_str(
             r#"
             {
@@ -2355,14 +2363,14 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         let mut lookup = BTreeMap::new();
         lookup.insert("a".to_owned(), 0);
         lookup.insert("b".to_owned(), 1);
 
         let expected = Schema::Record(RecordSchema {
-            name: Name::new("test").unwrap(),
+            name: Name::new("test")?,
             aliases: None,
             doc: None,
             fields: vec![
@@ -2392,11 +2400,12 @@ mod tests {
         });
 
         assert_eq!(parsed, expected);
+
+        Ok(())
     }
 
-    // AVRO-3302
     #[test]
-    fn test_record_schema_with_currently_parsing_schema() {
+    fn test_avro_3302_record_schema_with_currently_parsing_schema() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -2416,7 +2425,7 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         let mut lookup = BTreeMap::new();
         lookup.insert("recordField".to_owned(), 0);
@@ -2426,7 +2435,7 @@ mod tests {
         node_lookup.insert("label".to_owned(), 0);
 
         let expected = Schema::Record(RecordSchema {
-            name: Name::new("test").unwrap(),
+            name: Name::new("test")?,
             aliases: None,
             doc: None,
             fields: vec![RecordField {
@@ -2435,7 +2444,7 @@ mod tests {
                 default: None,
                 aliases: None,
                 schema: Schema::Record(RecordSchema {
-                    name: Name::new("Node").unwrap(),
+                    name: Name::new("Node")?,
                     aliases: None,
                     doc: None,
                     fields: vec![
@@ -2455,7 +2464,7 @@ mod tests {
                             default: None,
                             aliases: None,
                             schema: Schema::Array(Box::new(Schema::Ref {
-                                name: Name::new("Node").unwrap(),
+                                name: Name::new("Node")?,
                             })),
                             order: RecordFieldOrder::Ascending,
                             position: 1,
@@ -2477,11 +2486,13 @@ mod tests {
         let canonical_form = &schema.canonical_form();
         let expected = r#"{"name":"test","type":"record","fields":[{"name":"recordField","type":{"name":"Node","type":"record","fields":[{"name":"label","type":"string"},{"name":"children","type":{"type":"array","items":"Node"}}]}}]}"#;
         assert_eq!(canonical_form, &expected);
+
+        Ok(())
     }
 
     // https://github.com/flavray/avro-rs/pull/99#issuecomment-1016948451
     #[test]
-    fn test_parsing_of_recursive_type_enum() {
+    fn test_parsing_of_recursive_type_enum() -> TestResult {
         let schema = r#"
     {
         "type": "record",
@@ -2525,14 +2536,16 @@ mod tests {
         }
         "#;
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let schema_str = schema.canonical_form();
         let expected = r#"{"name":"office.User","type":"record","fields":[{"name":"details","type":[{"name":"Employee","type":"record","fields":[{"name":"gender","type":{"name":"Gender","type":"enum","symbols":["male","female"]}}]},{"name":"Manager","type":"record","fields":[{"name":"gender","type":"Gender"}]}]}]}"#;
         assert_eq!(schema_str, expected);
+
+        Ok(())
     }
 
     #[test]
-    fn test_parsing_of_recursive_type_fixed() {
+    fn test_parsing_of_recursive_type_fixed() -> TestResult {
         let schema = r#"
     {
         "type": "record",
@@ -2573,15 +2586,16 @@ mod tests {
         }
         "#;
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let schema_str = schema.canonical_form();
         let expected = r#"{"name":"office.User","type":"record","fields":[{"name":"details","type":[{"name":"Employee","type":"record","fields":[{"name":"id","type":{"name":"EmployeeId","type":"fixed","size":16}}]},{"name":"Manager","type":"record","fields":[{"name":"id","type":"EmployeeId"}]}]}]}"#;
         assert_eq!(schema_str, expected);
+
+        Ok(())
     }
 
-    // AVRO-3302
     #[test]
-    fn test_record_schema_with_currently_parsing_schema_aliases() {
+    fn test_avro_3302_record_schema_with_currently_parsing_schema_aliases() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -2595,7 +2609,7 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         let mut lookup = BTreeMap::new();
         lookup.insert("value".to_owned(), 0);
@@ -2634,7 +2648,7 @@ mod tests {
                                 },
                             },
                         ])
-                        .unwrap(),
+                        ?,
                     ),
                     order: RecordFieldOrder::Ascending,
                     position: 1,
@@ -2649,11 +2663,12 @@ mod tests {
         let canonical_form = &schema.canonical_form();
         let expected = r#"{"name":"LongList","type":"record","fields":[{"name":"value","type":"long"},{"name":"next","type":["null","LongList"]}]}"#;
         assert_eq!(canonical_form, &expected);
+
+        Ok(())
     }
 
-    // AVRO-3370
     #[test]
-    fn test_record_schema_with_currently_parsing_schema_named_record() {
+    fn test_avro_3370_record_schema_with_currently_parsing_schema_named_record() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -2666,7 +2681,7 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         let mut lookup = BTreeMap::new();
         lookup.insert("value".to_owned(), 0);
@@ -2714,11 +2729,12 @@ mod tests {
         let canonical_form = &schema.canonical_form();
         let expected = r#"{"name":"record","type":"record","fields":[{"name":"value","type":"long"},{"name":"next","type":"record"}]}"#;
         assert_eq!(canonical_form, &expected);
+
+        Ok(())
     }
 
-    // AVRO-3370
     #[test]
-    fn test_record_schema_with_currently_parsing_schema_named_enum() {
+    fn test_avro_3370_record_schema_with_currently_parsing_schema_named_enum() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -2735,7 +2751,7 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         let mut lookup = BTreeMap::new();
         lookup.insert("enum".to_owned(), 0);
@@ -2796,11 +2812,12 @@ mod tests {
         let canonical_form = &schema.canonical_form();
         let expected = r#"{"name":"record","type":"record","fields":[{"name":"enum","type":{"name":"enum","type":"enum","symbols":["one","two","three"]}},{"name":"next","type":{"name":"enum","type":"enum","symbols":["one","two","three"]}}]}"#;
         assert_eq!(canonical_form, &expected);
+
+        Ok(())
     }
 
-    // AVRO-3370
     #[test]
-    fn test_record_schema_with_currently_parsing_schema_named_fixed() {
+    fn test_avro_3370_record_schema_with_currently_parsing_schema_named_fixed() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -2817,7 +2834,7 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         let mut lookup = BTreeMap::new();
         lookup.insert("fixed".to_owned(), 0);
@@ -2878,16 +2895,18 @@ mod tests {
         let canonical_form = &schema.canonical_form();
         let expected = r#"{"name":"record","type":"record","fields":[{"name":"fixed","type":{"name":"fixed","type":"fixed","size":456}},{"name":"next","type":{"name":"fixed","type":"fixed","size":456}}]}"#;
         assert_eq!(canonical_form, &expected);
+
+        Ok(())
     }
 
     #[test]
-    fn test_enum_schema() {
+    fn test_enum_schema() -> TestResult {
         let schema = Schema::parse_str(
             r#"{"type": "enum", "name": "Suit", "symbols": ["diamonds", "spades", "clubs", "hearts"]}"#,
-        ).unwrap();
+        )?;
 
         let expected = Schema::Enum(EnumSchema {
-            name: Name::new("Suit").unwrap(),
+            name: Name::new("Suit")?,
             aliases: None,
             doc: None,
             symbols: vec![
@@ -2900,32 +2919,38 @@ mod tests {
         });
 
         assert_eq!(expected, schema);
+
+        Ok(())
     }
 
     #[test]
-    fn test_enum_schema_duplicate() {
+    fn test_enum_schema_duplicate() -> TestResult {
         // Duplicate "diamonds"
         let schema = Schema::parse_str(
             r#"{"type": "enum", "name": "Suit", "symbols": ["diamonds", "spades", "clubs", "diamonds"]}"#,
         );
         assert!(schema.is_err());
+
+        Ok(())
     }
 
     #[test]
-    fn test_enum_schema_name() {
+    fn test_enum_schema_name() -> TestResult {
         // Invalid name "0000" does not match [A-Za-z_][A-Za-z0-9_]*
         let schema = Schema::parse_str(
             r#"{"type": "enum", "name": "Enum", "symbols": ["0000", "variant"]}"#,
         );
         assert!(schema.is_err());
+
+        Ok(())
     }
 
     #[test]
-    fn test_fixed_schema() {
-        let schema = Schema::parse_str(r#"{"type": "fixed", "name": "test", "size": 16}"#).unwrap();
+    fn test_fixed_schema() -> TestResult {
+        let schema = Schema::parse_str(r#"{"type": "fixed", "name": "test", "size": 16}"#)?;
 
         let expected = Schema::Fixed(FixedSchema {
-            name: Name::new("test").unwrap(),
+            name: Name::new("test")?,
             aliases: None,
             doc: None,
             size: 16usize,
@@ -2933,17 +2958,19 @@ mod tests {
         });
 
         assert_eq!(expected, schema);
+
+        Ok(())
     }
 
     #[test]
-    fn test_fixed_schema_with_documentation() {
+    fn test_fixed_schema_with_documentation() -> TestResult {
         let schema = Schema::parse_str(
             r#"{"type": "fixed", "name": "test", "size": 16, "doc": "FixedSchema documentation"}"#,
         )
-        .unwrap();
+        ?;
 
         let expected = Schema::Fixed(FixedSchema {
-            name: Name::new("test").unwrap(),
+            name: Name::new("test")?,
             aliases: None,
             doc: Some(String::from("FixedSchema documentation")),
             size: 16usize,
@@ -2951,27 +2978,31 @@ mod tests {
         });
 
         assert_eq!(expected, schema);
+
+        Ok(())
     }
 
     #[test]
-    fn test_no_documentation() {
+    fn test_no_documentation() -> TestResult {
         let schema =
             Schema::parse_str(r#"{"type": "enum", "name": "Coin", "symbols": ["heads", "tails"]}"#)
-                .unwrap();
+                ?;
 
         let doc = match schema {
             Schema::Enum(EnumSchema { doc, .. }) => doc,
-            _ => return,
+            _ => unreachable!(),
         };
 
         assert!(doc.is_none());
+
+        Ok(())
     }
 
     #[test]
-    fn test_documentation() {
+    fn test_documentation() -> TestResult {
         let schema = Schema::parse_str(
             r#"{"type": "enum", "name": "Coin", "doc": "Some documentation", "symbols": ["heads", "tails"]}"#
-        ).unwrap();
+        )?;
 
         let doc = match schema {
             Schema::Enum(EnumSchema { doc, .. }) => doc,
@@ -2979,6 +3010,8 @@ mod tests {
         };
 
         assert_eq!("Some documentation".to_owned(), doc.unwrap());
+
+        Ok(())
     }
 
     // Tests to ensure Schema is Send + Sync. These tests don't need to _do_ anything, if they can
@@ -3001,8 +3034,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(miri, ignore)] // Sha256 uses an inline assembly instructions which is not supported by miri
-    fn test_schema_fingerprint() {
+    fn test_schema_fingerprint() -> TestResult {
         use crate::rabin::Rabin;
         use md5::Md5;
         use sha2::Sha256;
@@ -3019,7 +3051,7 @@ mod tests {
     }
 "#;
 
-        let schema = Schema::parse_str(raw_schema).unwrap();
+        let schema = Schema::parse_str(raw_schema)?;
         assert_eq!(
             "abf662f831715ff78f88545a05a9262af75d6406b54e1a8a174ff1d2b75affc4",
             format!("{}", schema.fingerprint::<Sha256>())
@@ -3032,33 +3064,39 @@ mod tests {
         assert_eq!(
             "28cf0a67d9937bb3",
             format!("{}", schema.fingerprint::<Rabin>())
-        )
+        );
+
+        Ok(())
     }
 
     #[test]
-    fn test_logical_types() {
-        let schema = Schema::parse_str(r#"{"type": "int", "logicalType": "date"}"#).unwrap();
+    fn test_logical_types() -> TestResult {
+        let schema = Schema::parse_str(r#"{"type": "int", "logicalType": "date"}"#)?;
         assert_eq!(schema, Schema::Date);
 
         let schema =
-            Schema::parse_str(r#"{"type": "long", "logicalType": "timestamp-micros"}"#).unwrap();
+            Schema::parse_str(r#"{"type": "long", "logicalType": "timestamp-micros"}"#)?;
         assert_eq!(schema, Schema::TimestampMicros);
+
+        Ok(())
     }
 
     #[test]
-    fn test_nullable_logical_type() {
+    fn test_nullable_logical_type() -> TestResult {
         let schema = Schema::parse_str(
             r#"{"type": ["null", {"type": "long", "logicalType": "timestamp-micros"}]}"#,
         )
-        .unwrap();
+        ?;
         assert_eq!(
             schema,
-            Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::TimestampMicros]).unwrap())
+            Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::TimestampMicros])?)
         );
+
+        Ok(())
     }
 
     #[test]
-    fn record_field_order_from_str() {
+    fn record_field_order_from_str() -> TestResult {
         use std::str::FromStr;
 
         assert_eq!(
@@ -3074,11 +3112,12 @@ mod tests {
             RecordFieldOrder::Ignore
         );
         assert!(RecordFieldOrder::from_str("not an ordering").is_err());
+
+        Ok(())
     }
 
-    /// AVRO-3374
     #[test]
-    fn test_avro_3374_preserve_namespace_for_primitive() {
+    fn test_avro_3374_preserve_namespace_for_primitive() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -3091,17 +3130,19 @@ mod tests {
             }
             "#,
         )
-        .unwrap();
+        ?;
 
         let json = schema.canonical_form();
         assert_eq!(
             json,
             r#"{"name":"ns.int","type":"record","fields":[{"name":"value","type":"int"},{"name":"next","type":["null","ns.int"]}]}"#
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3433_preserve_schema_refs_in_json() {
+    fn test_avro_3433_preserve_schema_refs_in_json() -> TestResult {
         let schema = r#"
     {
       "name": "test.test",
@@ -3116,14 +3157,16 @@ mod tests {
     }
     "#;
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
 
         let expected = r#"{"name":"test.test","type":"record","fields":[{"name":"bar","type":{"name":"test.foo","type":"record","fields":[{"name":"id","type":"long"}]}},{"name":"baz","type":"test.foo"}]}"#;
         assert_eq!(schema.canonical_form(), expected);
+
+        Ok(())
     }
 
     #[test]
-    fn test_read_namespace_from_name() {
+    fn test_read_namespace_from_name() -> TestResult {
         let schema = r#"
     {
       "name": "space.name",
@@ -3137,17 +3180,19 @@ mod tests {
     }
     "#;
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         if let Schema::Record(RecordSchema { name, .. }) = schema {
             assert_eq!(name.name, "name");
             assert_eq!(name.namespace, Some("space".to_string()));
         } else {
             panic!("Expected a record schema!");
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_namespace_from_name_has_priority_over_from_field() {
+    fn test_namespace_from_name_has_priority_over_from_field() -> TestResult {
         let schema = r#"
     {
       "name": "space1.name",
@@ -3162,16 +3207,18 @@ mod tests {
     }
     "#;
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         if let Schema::Record(RecordSchema { name, .. }) = schema {
             assert_eq!(name.namespace, Some("space1".to_string()));
         } else {
             panic!("Expected a record schema!");
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_namespace_from_field() {
+    fn test_namespace_from_field() -> TestResult {
         let schema = r#"
     {
       "name": "name",
@@ -3186,20 +3233,24 @@ mod tests {
     }
     "#;
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         if let Schema::Record(RecordSchema { name, .. }) = schema {
             assert_eq!(name.namespace, Some("space2".to_string()));
         } else {
             panic!("Expected a record schema!");
         }
+
+        Ok(())
     }
 
     #[test]
     /// Zero-length namespace is considered as no-namespace.
-    fn test_namespace_from_name_with_empty_value() {
-        let name = Name::new(".name").unwrap();
+    fn test_namespace_from_name_with_empty_value() -> TestResult {
+        let name = Name::new(".name")?;
         assert_eq!(name.name, "name");
         assert_eq!(name.namespace, None);
+
+        Ok(())
     }
 
     #[test]
@@ -3221,7 +3272,7 @@ mod tests {
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_record_inherited_namespace() {
+    fn avro_3448_test_proper_resolution_inner_record_inherited_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3251,16 +3302,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.inner_record_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_record_qualified_namespace() {
+    fn avro_3448_test_proper_resolution_inner_record_qualified_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3290,16 +3343,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.inner_record_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_enum_inherited_namespace() {
+    fn avro_3448_test_proper_resolution_inner_enum_inherited_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3324,16 +3379,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.inner_enum_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_enum_qualified_namespace() {
+    fn avro_3448_test_proper_resolution_inner_enum_qualified_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3358,16 +3415,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.inner_enum_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_fixed_inherited_namespace() {
+    fn avro_3448_test_proper_resolution_inner_fixed_inherited_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3392,16 +3451,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.inner_fixed_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_fixed_qualified_namespace() {
+    fn avro_3448_test_proper_resolution_inner_fixed_qualified_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3426,16 +3487,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.inner_fixed_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_record_inner_namespace() {
+    fn avro_3448_test_proper_resolution_inner_record_inner_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3466,16 +3529,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "inner_space.inner_record_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_enum_inner_namespace() {
+    fn avro_3448_test_proper_resolution_inner_enum_inner_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3501,16 +3566,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "inner_space.inner_enum_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_resolution_inner_fixed_inner_namespace() {
+    fn avro_3448_test_proper_resolution_inner_fixed_inner_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3536,16 +3603,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "inner_space.inner_fixed_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_multi_level_resolution_inner_record_outer_namespace() {
+    fn avro_3448_test_proper_multi_level_resolution_inner_record_outer_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3587,7 +3656,7 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 3);
         for s in &[
@@ -3595,12 +3664,14 @@ mod tests {
             "space.middle_record_name",
             "space.inner_record_name",
         ] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_multi_level_resolution_inner_record_middle_namespace() {
+    fn avro_3448_test_proper_multi_level_resolution_inner_record_middle_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3643,7 +3714,7 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 3);
         for s in &[
@@ -3651,12 +3722,14 @@ mod tests {
             "middle_namespace.middle_record_name",
             "middle_namespace.inner_record_name",
         ] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_multi_level_resolution_inner_record_inner_namespace() {
+    fn avro_3448_test_proper_multi_level_resolution_inner_record_inner_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3700,7 +3773,7 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 3);
         for s in &[
@@ -3708,12 +3781,14 @@ mod tests {
             "middle_namespace.middle_record_name",
             "inner_namespace.inner_record_name",
         ] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_in_array_resolution_inherited_namespace() {
+    fn avro_3448_test_proper_in_array_resolution_inherited_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3743,16 +3818,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.in_array_record"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3448_test_proper_in_map_resolution_inherited_namespace() {
+    fn avro_3448_test_proper_in_map_resolution_inherited_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -3782,16 +3859,18 @@ mod tests {
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "space.in_map_record"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3466_test_to_json_inner_enum_inner_namespace() {
+    fn avro_3466_test_to_json_inner_enum_inner_namespace() -> TestResult {
         let schema = r#"
         {
         "name": "record_name",
@@ -3817,23 +3896,25 @@ mod tests {
         ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
 
         // confirm we have expected 2 full-names
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "inner_space.inner_enum_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
 
         // convert Schema back to JSON string
         let schema_str = serde_json::to_string(&schema).expect("test failed");
         let _schema = Schema::parse_str(&schema_str).expect("test failed");
         assert_eq!(schema, _schema);
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3466_test_to_json_inner_fixed_inner_namespace() {
+    fn avro_3466_test_to_json_inner_fixed_inner_namespace() -> TestResult {
         let schema = r#"
         {
         "name": "record_name",
@@ -3859,19 +3940,21 @@ mod tests {
         ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let rs = ResolvedSchema::try_from(&schema).expect("Schema didn't successfully parse");
 
         // confirm we have expected 2 full-names
         assert_eq!(rs.get_names().len(), 2);
         for s in &["space.record_name", "inner_space.inner_fixed_name"] {
-            assert!(rs.get_names().contains_key(&Name::new(s).unwrap()));
+            assert!(rs.get_names().contains_key(&Name::new(s)?));
         }
 
         // convert Schema back to JSON string
         let schema_str = serde_json::to_string(&schema).expect("test failed");
         let _schema = Schema::parse_str(&schema_str).expect("test failed");
         assert_eq!(schema, _schema);
+
+        Ok(())
     }
 
     fn assert_avro_3512_aliases(aliases: &Aliases) {
@@ -3889,7 +3972,7 @@ mod tests {
     }
 
     #[test]
-    fn avro_3512_alias_with_null_namespace_record() {
+    fn avro_3512_alias_with_null_namespace_record() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -3903,17 +3986,19 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         if let Schema::Record(RecordSchema { ref aliases, .. }) = schema {
             assert_avro_3512_aliases(aliases);
         } else {
             panic!("The Schema should be a record: {schema:?}");
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3512_alias_with_null_namespace_enum() {
+    fn avro_3512_alias_with_null_namespace_enum() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -3927,17 +4012,19 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         if let Schema::Enum(EnumSchema { ref aliases, .. }) = schema {
             assert_avro_3512_aliases(aliases);
         } else {
             panic!("The Schema should be an enum: {schema:?}");
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3512_alias_with_null_namespace_fixed() {
+    fn avro_3512_alias_with_null_namespace_fixed() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -3949,17 +4036,19 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
         if let Schema::Fixed(FixedSchema { ref aliases, .. }) = schema {
             assert_avro_3512_aliases(aliases);
         } else {
             panic!("The Schema should be a fixed: {schema:?}");
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3518_serialize_aliases_record() {
+    fn avro_3518_serialize_aliases_record() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -3979,19 +4068,21 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
-        let value = serde_json::to_value(&schema).unwrap();
-        let serialized = serde_json::to_string(&value).unwrap();
+        let value = serde_json::to_value(&schema)?;
+        let serialized = serde_json::to_string(&value)?;
         assert_eq!(
             r#"{"aliases":["space.b","x.y","c"],"fields":[{"aliases":["time1","ns.time2"],"default":123,"name":"time","type":"long"}],"name":"a","namespace":"space","type":"record"}"#,
             &serialized
         );
-        assert_eq!(schema, Schema::parse_str(&serialized).unwrap());
+        assert_eq!(schema, Schema::parse_str(&serialized)?);
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3518_serialize_aliases_enum() {
+    fn avro_3518_serialize_aliases_enum() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -4005,19 +4096,21 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
-        let value = serde_json::to_value(&schema).unwrap();
-        let serialized = serde_json::to_string(&value).unwrap();
+        let value = serde_json::to_value(&schema)?;
+        let serialized = serde_json::to_string(&value)?;
         assert_eq!(
             r#"{"aliases":["space.b","x.y","c"],"name":"a","namespace":"space","symbols":["symbol1","symbol2"],"type":"enum"}"#,
             &serialized
         );
-        assert_eq!(schema, Schema::parse_str(&serialized).unwrap());
+        assert_eq!(schema, Schema::parse_str(&serialized)?);
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3518_serialize_aliases_fixed() {
+    fn avro_3518_serialize_aliases_fixed() -> TestResult {
         let schema = Schema::parse_str(
             r#"
             {
@@ -4029,19 +4122,21 @@ mod tests {
             }
         "#,
         )
-        .unwrap();
+        ?;
 
-        let value = serde_json::to_value(&schema).unwrap();
-        let serialized = serde_json::to_string(&value).unwrap();
+        let value = serde_json::to_value(&schema)?;
+        let serialized = serde_json::to_string(&value)?;
         assert_eq!(
             r#"{"aliases":["space.b","x.y","c"],"name":"a","namespace":"space","size":12,"type":"fixed"}"#,
             &serialized
         );
-        assert_eq!(schema, Schema::parse_str(&serialized).unwrap());
+        assert_eq!(schema, Schema::parse_str(&serialized)?);
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3130_parse_anonymous_union_type() {
+    fn avro_3130_parse_anonymous_union_type() -> TestResult {
         let schema_str = r#"
         {
             "type": "record",
@@ -4061,10 +4156,10 @@ mod tests {
             ]
         }
         "#;
-        let schema = Schema::parse_str(schema_str).unwrap();
+        let schema = Schema::parse_str(schema_str)?;
 
         if let Schema::Record(RecordSchema { name, fields, .. }) = schema {
-            assert_eq!(name, Name::new("AccountEvent").unwrap());
+            assert_eq!(name, Name::new("AccountEvent")?);
 
             let field = &fields[0];
             assert_eq!(&field.name, "NullableLongArray");
@@ -4087,10 +4182,12 @@ mod tests {
         } else {
             panic!("Expected Schema::Record");
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_custom_attributes_schema_without_attributes() {
+    fn avro_custom_attributes_schema_without_attributes() -> TestResult {
         let schemata_str = [
             r#"
             {
@@ -4118,9 +4215,11 @@ mod tests {
             "#,
         ];
         for schema_str in schemata_str.iter() {
-            let schema = Schema::parse_str(schema_str).unwrap();
+            let schema = Schema::parse_str(schema_str)?;
             assert_eq!(schema.custom_attributes(), Some(&Default::default()));
         }
+
+        Ok(())
     }
 
     const CUSTOM_ATTRS_SUFFIX: &str = r#"
@@ -4134,7 +4233,7 @@ mod tests {
         "#;
 
     #[test]
-    fn avro_3609_custom_attributes_schema_with_attributes() {
+    fn avro_3609_custom_attributes_schema_with_attributes() -> TestResult {
         let schemata_str = [
             r#"
             {
@@ -4175,13 +4274,15 @@ mod tests {
                     .replace("{{{}}}", CUSTOM_ATTRS_SUFFIX)
                     .as_str(),
             )
-            .unwrap();
+            ?;
 
             assert_eq!(
                 schema.custom_attributes(),
                 Some(&expected_custom_attibutes())
             );
         }
+
+        Ok(())
     }
 
     fn expected_custom_attibutes() -> BTreeMap<String, Value> {
@@ -4200,7 +4301,7 @@ mod tests {
     }
 
     #[test]
-    fn avro_3609_custom_attributes_record_field_without_attributes() {
+    fn avro_3609_custom_attributes_record_field_without_attributes() -> TestResult {
         let schema_str = String::from(
             r#"
             {
@@ -4219,11 +4320,11 @@ mod tests {
         );
 
         let schema =
-            Schema::parse_str(schema_str.replace("{{{}}}", CUSTOM_ATTRS_SUFFIX).as_str()).unwrap();
+            Schema::parse_str(schema_str.replace("{{{}}}", CUSTOM_ATTRS_SUFFIX).as_str())?;
 
         match schema {
             Schema::Record(RecordSchema { name, fields, .. }) => {
-                assert_eq!(name, Name::new("Rec").unwrap());
+                assert_eq!(name, Name::new("Rec")?);
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
                 assert_eq!(&field.name, "field_one");
@@ -4231,10 +4332,12 @@ mod tests {
             }
             _ => panic!("Expected Schema::Record"),
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3625_null_is_first() {
+    fn avro_3625_null_is_first() -> TestResult {
         let schema_str = String::from(
             r#"
             {
@@ -4247,11 +4350,11 @@ mod tests {
         "#,
         );
 
-        let schema = Schema::parse_str(&schema_str).unwrap();
+        let schema = Schema::parse_str(&schema_str)?;
 
         match schema {
             Schema::Record(RecordSchema { name, fields, .. }) => {
-                assert_eq!(name, Name::new("union_schema_test").unwrap());
+                assert_eq!(name, Name::new("union_schema_test")?);
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
                 assert_eq!(&field.name, "a");
@@ -4268,10 +4371,12 @@ mod tests {
             }
             _ => panic!("Expected Schema::Record"),
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3625_null_is_last() {
+    fn avro_3625_null_is_last() -> TestResult {
         let schema_str = String::from(
             r#"
             {
@@ -4284,11 +4389,11 @@ mod tests {
         "#,
         );
 
-        let schema = Schema::parse_str(&schema_str).unwrap();
+        let schema = Schema::parse_str(&schema_str)?;
 
         match schema {
             Schema::Record(RecordSchema { name, fields, .. }) => {
-                assert_eq!(name, Name::new("union_schema_test").unwrap());
+                assert_eq!(name, Name::new("union_schema_test")?);
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
                 assert_eq!(&field.name, "a");
@@ -4304,10 +4409,12 @@ mod tests {
             }
             _ => panic!("Expected Schema::Record"),
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3625_null_is_the_middle() {
+    fn avro_3625_null_is_the_middle() -> TestResult {
         let schema_str = String::from(
             r#"
             {
@@ -4320,11 +4427,11 @@ mod tests {
         "#,
         );
 
-        let schema = Schema::parse_str(&schema_str).unwrap();
+        let schema = Schema::parse_str(&schema_str)?;
 
         match schema {
             Schema::Record(RecordSchema { name, fields, .. }) => {
-                assert_eq!(name, Name::new("union_schema_test").unwrap());
+                assert_eq!(name, Name::new("union_schema_test")?);
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
                 assert_eq!(&field.name, "a");
@@ -4341,10 +4448,12 @@ mod tests {
             }
             _ => panic!("Expected Schema::Record"),
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3649_default_notintfirst() {
+    fn avro_3649_default_notintfirst() -> TestResult {
         let schema_str = String::from(
             r#"
             {
@@ -4357,11 +4466,11 @@ mod tests {
         "#,
         );
 
-        let schema = Schema::parse_str(&schema_str).unwrap();
+        let schema = Schema::parse_str(&schema_str)?;
 
         match schema {
             Schema::Record(RecordSchema { name, fields, .. }) => {
-                assert_eq!(name, Name::new("union_schema_test").unwrap());
+                assert_eq!(name, Name::new("union_schema_test")?);
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
                 assert_eq!(&field.name, "a");
@@ -4377,10 +4486,12 @@ mod tests {
             }
             _ => panic!("Expected Schema::Record"),
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3709_parsing_of_record_field_aliases() {
+    fn avro_3709_parsing_of_record_field_aliases() -> TestResult {
         let schema = r#"
         {
           "name": "rec",
@@ -4395,7 +4506,7 @@ mod tests {
         }
         "#;
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         if let Schema::Record(RecordSchema { fields, .. }) = schema {
             let num_field = &fields[0];
             assert_eq!(num_field.name, "num");
@@ -4403,10 +4514,12 @@ mod tests {
         } else {
             panic!("Expected a record schema!");
         }
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3735_parse_enum_namespace() {
+    fn avro_3735_parse_enum_namespace() -> TestResult {
         let schema = r#"
         {
             "type": "record",
@@ -4453,24 +4566,26 @@ mod tests {
             pub bar_use: Bar,
         }
 
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
 
         let foo = Foo {
             bar_init: Bar::Bar0,
             bar_use: Bar::Bar1,
         };
 
-        let avro_value = crate::to_value(foo).unwrap();
+        let avro_value = crate::to_value(foo)?;
         assert!(avro_value.validate(&schema));
 
         let mut writer = crate::Writer::new(&schema, Vec::new());
 
         // schema validation happens here
-        writer.append(avro_value).unwrap();
+        writer.append(avro_value)?;
+
+        Ok(())
     }
 
     #[test]
-    fn avro_3755_deserialize() {
+    fn avro_3755_deserialize() -> TestResult {
         #[derive(
             Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, serde::Deserialize, serde::Serialize,
         )]
@@ -4543,21 +4658,21 @@ mod tests {
             ]
             }"#;
 
-        let writer_schema = Schema::parse_str(writer_schema).unwrap();
+        let writer_schema = Schema::parse_str(writer_schema)?;
         let foo = Foo {
             bar_init: Bar::Bar0,
             bar_use: Bar::Bar1,
         };
-        let avro_value = crate::to_value(foo).unwrap();
+        let avro_value = crate::to_value(foo)?;
         assert!(
             avro_value.validate(&writer_schema),
             "value is valid for schema",
         );
-        let datum = crate::to_avro_datum(&writer_schema, avro_value).unwrap();
+        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
         let mut x = &datum[..];
-        let reader_schema = Schema::parse_str(reader_schema).unwrap();
+        let reader_schema = Schema::parse_str(reader_schema)?;
         let deser_value =
-            crate::from_avro_datum(&writer_schema, &mut x, Some(&reader_schema)).unwrap();
+            crate::from_avro_datum(&writer_schema, &mut x, Some(&reader_schema))?;
         match deser_value {
             types::Value::Record(fields) => {
                 assert_eq!(fields.len(), 2);
@@ -4568,5 +4683,7 @@ mod tests {
             }
             _ => panic!("Expected Value::Record"),
         }
+
+        Ok(())
     }
 }
diff --git a/lang/rust/avro/src/schema_compatibility.rs b/lang/rust/avro/src/schema_compatibility.rs
index aad8fde36..dcd70f2b1 100644
--- a/lang/rust/avro/src/schema_compatibility.rs
+++ b/lang/rust/avro/src/schema_compatibility.rs
@@ -326,6 +326,7 @@ impl SchemaCompatibility {
 
 #[cfg(test)]
 mod tests {
+    use apache_avro_test_helper::TestResult;
     use super::*;
 
     fn int_array_schema() -> Schema {
@@ -589,15 +590,14 @@ mod tests {
     }
 
     #[test]
-    fn test_missing_field() {
+    fn test_missing_field() -> TestResult {
         let reader_schema = Schema::parse_str(
             r#"
       {"type":"record", "name":"Record", "fields":[
         {"name":"oldfield1", "type":"int"}
       ]}
 "#,
-        )
-        .unwrap();
+        )?;
         assert!(SchemaCompatibility::can_read(
             &writer_schema(),
             &reader_schema,
@@ -606,18 +606,19 @@ mod tests {
             &reader_schema,
             &writer_schema()
         ));
+
+        Ok(())
     }
 
     #[test]
-    fn test_missing_second_field() {
+    fn test_missing_second_field() -> TestResult {
         let reader_schema = Schema::parse_str(
             r#"
         {"type":"record", "name":"Record", "fields":[
           {"name":"oldfield2", "type":"string"}
         ]}
 "#,
-        )
-        .unwrap();
+        )?;
         assert!(SchemaCompatibility::can_read(
             &writer_schema(),
             &reader_schema
@@ -626,10 +627,12 @@ mod tests {
             &reader_schema,
             &writer_schema()
         ));
+
+        Ok(())
     }
 
     #[test]
-    fn test_all_fields() {
+    fn test_all_fields() -> TestResult {
         let reader_schema = Schema::parse_str(
             r#"
         {"type":"record", "name":"Record", "fields":[
@@ -637,8 +640,7 @@ mod tests {
           {"name":"oldfield2", "type":"string"}
         ]}
 "#,
-        )
-        .unwrap();
+        )?;
         assert!(SchemaCompatibility::can_read(
             &writer_schema(),
             &reader_schema
@@ -647,10 +649,12 @@ mod tests {
             &reader_schema,
             &writer_schema()
         ));
+
+        Ok(())
     }
 
     #[test]
-    fn test_new_field_with_default() {
+    fn test_new_field_with_default() -> TestResult {
         let reader_schema = Schema::parse_str(
             r#"
         {"type":"record", "name":"Record", "fields":[
@@ -658,8 +662,7 @@ mod tests {
           {"name":"newfield1", "type":"int", "default":42}
         ]}
 "#,
-        )
-        .unwrap();
+        )?;
         assert!(SchemaCompatibility::can_read(
             &writer_schema(),
             &reader_schema
@@ -668,10 +671,12 @@ mod tests {
             &reader_schema,
             &writer_schema()
         ));
+
+        Ok(())
     }
 
     #[test]
-    fn test_new_field() {
+    fn test_new_field() -> TestResult {
         let reader_schema = Schema::parse_str(
             r#"
         {"type":"record", "name":"Record", "fields":[
@@ -679,8 +684,7 @@ mod tests {
           {"name":"newfield1", "type":"int"}
         ]}
 "#,
-        )
-        .unwrap();
+        )?;
         assert!(!SchemaCompatibility::can_read(
             &writer_schema(),
             &reader_schema
@@ -689,6 +693,8 @@ mod tests {
             &reader_schema,
             &writer_schema()
         ));
+
+        Ok(())
     }
 
     #[test]
@@ -720,7 +726,7 @@ mod tests {
     }
 
     #[test]
-    fn test_union_reader_writer_subset_incompatiblity() {
+    fn test_union_reader_writer_subset_incompatibility() {
         // reader union schema must contain all writer union branches
         let union_writer = union_schema(vec![Schema::Int, Schema::String]);
         let union_reader = union_schema(vec![Schema::String]);
@@ -730,15 +736,14 @@ mod tests {
     }
 
     #[test]
-    fn test_incompatible_record_field() {
+    fn test_incompatible_record_field() -> TestResult {
         let string_schema = Schema::parse_str(
             r#"
         {"type":"record", "name":"MyRecord", "namespace":"ns", "fields": [
             {"name":"field1", "type":"string"}
         ]}
         "#,
-        )
-        .unwrap();
+        )?;
 
         let int_schema = Schema::parse_str(
             r#"
@@ -746,25 +751,26 @@ mod tests {
         {"name":"field1", "type":"int"}
       ]}
 "#,
-        )
-        .unwrap();
+        )?;
 
         assert!(!SchemaCompatibility::can_read(&string_schema, &int_schema));
+
+        Ok(())
     }
 
     #[test]
-    fn test_enum_symbols() {
+    fn test_enum_symbols() -> TestResult {
         let enum_schema1 = Schema::parse_str(
             r#"
       {"type":"enum", "name":"MyEnum", "symbols":["A","B"]}
 "#,
-        )
-        .unwrap();
+        )?;
         let enum_schema2 =
-            Schema::parse_str(r#"{"type":"enum", "name":"MyEnum", "symbols":["A","B","C"]}"#)
-                .unwrap();
+            Schema::parse_str(r#"{"type":"enum", "name":"MyEnum", "symbols":["A","B","C"]}"#)?;
         assert!(!SchemaCompatibility::can_read(&enum_schema2, &enum_schema1));
         assert!(SchemaCompatibility::can_read(&enum_schema1, &enum_schema2));
+
+        Ok(())
     }
 
     fn point_2d_schema() -> Schema {
diff --git a/lang/rust/avro/src/ser.rs b/lang/rust/avro/src/ser.rs
index 2237c1d99..a2567f64f 100644
--- a/lang/rust/avro/src/ser.rs
+++ b/lang/rust/avro/src/ser.rs
@@ -492,6 +492,7 @@ mod tests {
     use pretty_assertions::assert_eq;
     use serde::{Deserialize, Serialize};
     use std::sync::atomic::Ordering;
+    use apache_avro_test_helper::TestResult;
 
     #[derive(Debug, Deserialize, Serialize, Clone)]
     struct Test {
@@ -683,7 +684,7 @@ mod tests {
     }
 
     #[test]
-    fn test_to_value() {
+    fn test_to_value() -> TestResult {
         let test = Test {
             a: 27,
             b: "foo".to_owned(),
@@ -693,7 +694,7 @@ mod tests {
             ("b".to_owned(), Value::String("foo".to_owned())),
         ]);
 
-        assert_eq!(to_value(test.clone()).unwrap(), expected);
+        assert_eq!(to_value(test.clone())?, expected);
 
         let test_inner = TestInner { a: test, b: 35 };
 
@@ -708,11 +709,13 @@ mod tests {
             ("b".to_owned(), Value::Int(35)),
         ]);
 
-        assert_eq!(to_value(test_inner).unwrap(), expected_inner);
+        assert_eq!(to_value(test_inner)?, expected_inner);
+
+        Ok(())
     }
 
     #[test]
-    fn test_to_value_unit_enum() {
+    fn test_to_value_unit_enum() -> TestResult {
         let test = TestUnitExternalEnum {
             a: UnitExternalEnum::Val1,
         };
@@ -720,7 +723,7 @@ mod tests {
         let expected = Value::Record(vec![("a".to_owned(), Value::Enum(0, "Val1".to_owned()))]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "Error serializing unit external enum"
         );
@@ -735,7 +738,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "Error serializing unit internal enum"
         );
@@ -750,7 +753,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "Error serializing unit adjacent enum"
         );
@@ -762,14 +765,16 @@ mod tests {
         let expected = Value::Record(vec![("a".to_owned(), Value::Null)]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "Error serializing unit untagged enum"
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_to_value_single_value_enum() {
+    fn test_to_value_single_value_enum() -> TestResult {
         let test = TestSingleValueExternalEnum {
             a: SingleValueExternalEnum::Double(64.0),
         };
@@ -786,7 +791,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "Error serializing single value external enum"
         );
@@ -811,7 +816,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "Error serializing single value adjacent enum"
         );
@@ -823,14 +828,16 @@ mod tests {
         let expected = Value::Record(vec![("a".to_owned(), Value::Double(64.0))]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "Error serializing single value untagged enum"
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_to_value_struct_enum() {
+    fn test_to_value_struct_enum() -> TestResult {
         let test = TestStructExternalEnum {
             a: StructExternalEnum::Val1 { x: 1.0, y: 2.0 },
         };
@@ -852,7 +859,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing struct external enum"
         );
@@ -872,7 +879,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing struct internal enum"
         );
@@ -895,7 +902,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing struct adjacent enum"
         );
@@ -912,7 +919,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing struct untagged enum"
         );
@@ -934,14 +941,16 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing struct untagged enum variant"
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_to_value_tuple_enum() {
+    fn test_to_value_tuple_enum() -> TestResult {
         let test = TestTupleExternalEnum {
             a: TupleExternalEnum::Val2(1.0, 2.0, 3.0),
         };
@@ -962,7 +971,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing tuple external enum"
         );
@@ -983,7 +992,7 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing tuple adjacent enum"
         );
@@ -998,10 +1007,12 @@ mod tests {
         )]);
 
         assert_eq!(
-            to_value(test).unwrap(),
+            to_value(test)?,
             expected,
             "error serializing tuple untagged enum"
         );
+
+        Ok(())
     }
 
     #[test]
diff --git a/lang/rust/avro/src/types.rs b/lang/rust/avro/src/types.rs
index 93e81e98e..e8d4d8774 100644
--- a/lang/rust/avro/src/types.rs
+++ b/lang/rust/avro/src/types.rs
@@ -1031,9 +1031,10 @@ mod tests {
     use apache_avro_test_helper::logger::{assert_logged, assert_not_logged};
     use pretty_assertions::assert_eq;
     use uuid::Uuid;
+    use apache_avro_test_helper::TestResult;
 
     #[test]
-    fn validate() {
+    fn validate() -> TestResult {
         let value_schema_valid = vec![
             (Value::Int(42), Schema::Int, true, ""),
             (Value::Int(43), Schema::Long, true, ""),
@@ -1047,19 +1048,19 @@ mod tests {
             ),
             (
                 Value::Union(0, Box::new(Value::Null)),
-                Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()),
+                Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?),
                 true,
                 "",
             ),
             (
                 Value::Union(1, Box::new(Value::Int(42))),
-                Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()),
+                Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?),
                 true,
                 "",
             ),
             (
                 Value::Union(0, Box::new(Value::Null)),
-                Schema::Union(UnionSchema::new(vec![Schema::Double, Schema::Int]).unwrap()),
+                Schema::Union(UnionSchema::new(vec![Schema::Double, Schema::Int])?),
                 false,
                 "Invalid value: Union(0, Null) for schema: Union(UnionSchema { schemas: [Double, Int], variant_index: {Int: 1, Double: 0} }). Reason: Unsupported value-schema combination",
             ),
@@ -1072,7 +1073,7 @@ mod tests {
                         Schema::String,
                         Schema::Int,
                     ])
-                    .unwrap(),
+                    ?,
                 ),
                 true,
                 "",
@@ -1080,14 +1081,14 @@ mod tests {
             (
                 Value::Union(1, Box::new(Value::Long(42i64))),
                 Schema::Union(
-                    UnionSchema::new(vec![Schema::Null, Schema::TimestampMillis]).unwrap(),
+                    UnionSchema::new(vec![Schema::Null, Schema::TimestampMillis])?,
                 ),
                 true,
                 "",
             ),
             (
                 Value::Union(2, Box::new(Value::Long(1_i64))),
-                Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap()),
+                Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?),
                 false,
                 "Invalid value: Union(2, Long(1)) for schema: Union(UnionSchema { schemas: [Null, Int], variant_index: {Null: 0, Int: 1} }). Reason: No schema in the union at position '2'",
             ),
@@ -1178,10 +1179,12 @@ mod tests {
                 assert_eq!(expected_err_message, full_err_message);
             }
         }
+
+        Ok(())
     }
 
     #[test]
-    fn validate_fixed() {
+    fn validate_fixed() -> TestResult {
         let schema = Schema::Fixed(FixedSchema {
             size: 4,
             name: Name::new("some_fixed").unwrap(),
@@ -1211,10 +1214,12 @@ mod tests {
             )
             .as_str(),
         );
+
+        Ok(())
     }
 
     #[test]
-    fn validate_enum() {
+    fn validate_enum() -> TestResult {
         let schema = Schema::Enum(EnumSchema {
             name: Name::new("some_enum").unwrap(),
             aliases: None,
@@ -1283,10 +1288,12 @@ mod tests {
             )
             .as_str(),
         );
+
+        Ok(())
     }
 
     #[test]
-    fn validate_record() {
+    fn validate_record() -> TestResult {
         // {
         //    "type": "record",
         //    "fields": [
@@ -1330,7 +1337,7 @@ mod tests {
                     default: Some(JsonValue::Null),
                     aliases: None,
                     schema: Schema::Union(
-                        UnionSchema::new(vec![Schema::Null, Schema::Int]).unwrap(),
+                        UnionSchema::new(vec![Schema::Null, Schema::Int])?,
                     ),
                     order: RecordFieldOrder::Ascending,
                     position: 2,
@@ -1422,7 +1429,7 @@ mod tests {
 Field with name '"b"' is not a member of the map items"#,
         );
 
-        let union_schema = Schema::Union(UnionSchema::new(vec![Schema::Null, schema]).unwrap());
+        let union_schema = Schema::Union(UnionSchema::new(vec![Schema::Null, schema])?);
 
         assert!(Value::Union(
             1,
@@ -1445,33 +1452,41 @@ Field with name '"b"' is not a member of the map items"#,
             ))
         )
         .validate(&union_schema));
+
+        Ok(())
     }
 
     #[test]
-    fn resolve_bytes_ok() {
+    fn resolve_bytes_ok() -> TestResult {
         let value = Value::Array(vec![Value::Int(0), Value::Int(42)]);
         assert_eq!(
-            value.resolve(&Schema::Bytes).unwrap(),
+            value.resolve(&Schema::Bytes)?,
             Value::Bytes(vec![0u8, 42u8])
         );
+
+        Ok(())
     }
 
     #[test]
-    fn resolve_string_from_bytes() {
+    fn resolve_string_from_bytes() -> TestResult {
         let value = Value::Bytes(vec![97, 98, 99]);
         assert_eq!(
-            value.resolve(&Schema::String).unwrap(),
+            value.resolve(&Schema::String)?,
             Value::String("abc".to_string())
         );
+
+        Ok(())
     }
 
     #[test]
-    fn resolve_string_from_fixed() {
+    fn resolve_string_from_fixed() -> TestResult {
         let value = Value::Fixed(3, vec![97, 98, 99]);
         assert_eq!(
-            value.resolve(&Schema::String).unwrap(),
+            value.resolve(&Schema::String)?,
             Value::String("abc".to_string())
         );
+
+        Ok(())
     }
 
     #[test]
@@ -1481,7 +1496,7 @@ Field with name '"b"' is not a member of the map items"#,
     }
 
     #[test]
-    fn resolve_decimal_bytes() {
+    fn resolve_decimal_bytes() -> TestResult {
         let value = Value::Decimal(Decimal::from(vec![1, 2]));
         value
             .clone()
@@ -1490,8 +1505,10 @@ Field with name '"b"' is not a member of the map items"#,
                 scale: 4,
                 inner: Box::new(Schema::Bytes),
             }))
-            .unwrap();
+            ?;
         assert!(value.resolve(&Schema::String).is_err());
+
+        Ok(())
     }
 
     #[test]
@@ -1592,10 +1609,12 @@ Field with name '"b"' is not a member of the map items"#,
     }
 
     #[test]
-    fn resolve_uuid() {
-        let value = Value::Uuid(Uuid::parse_str("1481531d-ccc9-46d9-a56f-5b67459c0537").unwrap());
+    fn resolve_uuid() -> TestResult {
+        let value = Value::Uuid(Uuid::parse_str("1481531d-ccc9-46d9-a56f-5b67459c0537")?);
         assert!(value.clone().resolve(&Schema::Uuid).is_ok());
         assert!(value.resolve(&Schema::TimestampMicros).is_err());
+
+        Ok(())
     }
 
     #[test]
@@ -1605,7 +1624,7 @@ Field with name '"b"' is not a member of the map items"#,
     }
 
     #[test]
-    fn test_avro_3621_resolve_to_nullable_union() {
+    fn test_avro_3621_resolve_to_nullable_union() -> TestResult {
         let schema = Schema::parse_str(
             r#"{
             "type": "record",
@@ -1639,7 +1658,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let value = Value::Record(vec![(
             "event".to_string(),
@@ -1652,33 +1671,35 @@ Field with name '"b"' is not a member of the map items"#,
             Value::Record(vec![("size".to_string(), Value::Int(1))]),
         )]);
         assert!(value.resolve(&schema).is_err());
+
+        Ok(())
     }
 
     #[test]
-    fn json_from_avro() {
-        assert_eq!(JsonValue::try_from(Value::Null).unwrap(), JsonValue::Null);
+    fn json_from_avro() -> TestResult {
+        assert_eq!(JsonValue::try_from(Value::Null)?, JsonValue::Null);
         assert_eq!(
-            JsonValue::try_from(Value::Boolean(true)).unwrap(),
+            JsonValue::try_from(Value::Boolean(true))?,
             JsonValue::Bool(true)
         );
         assert_eq!(
-            JsonValue::try_from(Value::Int(1)).unwrap(),
+            JsonValue::try_from(Value::Int(1))?,
             JsonValue::Number(1.into())
         );
         assert_eq!(
-            JsonValue::try_from(Value::Long(1)).unwrap(),
+            JsonValue::try_from(Value::Long(1))?,
             JsonValue::Number(1.into())
         );
         assert_eq!(
-            JsonValue::try_from(Value::Float(1.0)).unwrap(),
+            JsonValue::try_from(Value::Float(1.0))?,
             JsonValue::Number(Number::from_f64(1.0).unwrap())
         );
         assert_eq!(
-            JsonValue::try_from(Value::Double(1.0)).unwrap(),
+            JsonValue::try_from(Value::Double(1.0))?,
             JsonValue::Number(Number::from_f64(1.0).unwrap())
         );
         assert_eq!(
-            JsonValue::try_from(Value::Bytes(vec![1, 2, 3])).unwrap(),
+            JsonValue::try_from(Value::Bytes(vec![1, 2, 3]))?,
             JsonValue::Array(vec![
                 JsonValue::Number(1.into()),
                 JsonValue::Number(2.into()),
@@ -1686,11 +1707,11 @@ Field with name '"b"' is not a member of the map items"#,
             ])
         );
         assert_eq!(
-            JsonValue::try_from(Value::String("test".into())).unwrap(),
+            JsonValue::try_from(Value::String("test".into()))?,
             JsonValue::String("test".into())
         );
         assert_eq!(
-            JsonValue::try_from(Value::Fixed(3, vec![1, 2, 3])).unwrap(),
+            JsonValue::try_from(Value::Fixed(3, vec![1, 2, 3]))?,
             JsonValue::Array(vec![
                 JsonValue::Number(1.into()),
                 JsonValue::Number(2.into()),
@@ -1698,12 +1719,12 @@ Field with name '"b"' is not a member of the map items"#,
             ])
         );
         assert_eq!(
-            JsonValue::try_from(Value::Enum(1, "test_enum".into())).unwrap(),
+            JsonValue::try_from(Value::Enum(1, "test_enum".into()))?,
             JsonValue::String("test_enum".into())
         );
         assert_eq!(
             JsonValue::try_from(Value::Union(1, Box::new(Value::String("test_enum".into()))))
-                .unwrap(),
+                ?,
             JsonValue::String("test_enum".into())
         );
         assert_eq!(
@@ -1712,7 +1733,7 @@ Field with name '"b"' is not a member of the map items"#,
                 Value::Int(2),
                 Value::Int(3)
             ]))
-            .unwrap(),
+            ?,
             JsonValue::Array(vec![
                 JsonValue::Number(1.into()),
                 JsonValue::Number(2.into()),
@@ -1729,7 +1750,7 @@ Field with name '"b"' is not a member of the map items"#,
                 .into_iter()
                 .collect()
             ))
-            .unwrap(),
+            ?,
             JsonValue::Object(
                 vec![
                     ("v1".to_string(), JsonValue::Number(1.into())),
@@ -1746,7 +1767,7 @@ Field with name '"b"' is not a member of the map items"#,
                 ("v2".to_string(), Value::Int(2)),
                 ("v3".to_string(), Value::Int(3))
             ]))
-            .unwrap(),
+            ?,
             JsonValue::Object(
                 vec![
                     ("v1".to_string(), JsonValue::Number(1.into())),
@@ -1758,11 +1779,11 @@ Field with name '"b"' is not a member of the map items"#,
             )
         );
         assert_eq!(
-            JsonValue::try_from(Value::Date(1)).unwrap(),
+            JsonValue::try_from(Value::Date(1))?,
             JsonValue::Number(1.into())
         );
         assert_eq!(
-            JsonValue::try_from(Value::Decimal(vec![1, 2, 3].into())).unwrap(),
+            JsonValue::try_from(Value::Decimal(vec![1, 2, 3].into()))?,
             JsonValue::Array(vec![
                 JsonValue::Number(1.into()),
                 JsonValue::Number(2.into()),
@@ -1770,26 +1791,26 @@ Field with name '"b"' is not a member of the map items"#,
             ])
         );
         assert_eq!(
-            JsonValue::try_from(Value::TimeMillis(1)).unwrap(),
+            JsonValue::try_from(Value::TimeMillis(1))?,
             JsonValue::Number(1.into())
         );
         assert_eq!(
-            JsonValue::try_from(Value::TimeMicros(1)).unwrap(),
+            JsonValue::try_from(Value::TimeMicros(1))?,
             JsonValue::Number(1.into())
         );
         assert_eq!(
-            JsonValue::try_from(Value::TimestampMillis(1)).unwrap(),
+            JsonValue::try_from(Value::TimestampMillis(1))?,
             JsonValue::Number(1.into())
         );
         assert_eq!(
-            JsonValue::try_from(Value::TimestampMicros(1)).unwrap(),
+            JsonValue::try_from(Value::TimestampMicros(1))?,
             JsonValue::Number(1.into())
         );
         assert_eq!(
             JsonValue::try_from(Value::Duration(
                 [1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8].into()
             ))
-            .unwrap(),
+            ?,
             JsonValue::Array(vec![
                 JsonValue::Number(1.into()),
                 JsonValue::Number(2.into()),
@@ -1807,15 +1828,17 @@ Field with name '"b"' is not a member of the map items"#,
         );
         assert_eq!(
             JsonValue::try_from(Value::Uuid(
-                Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8").unwrap()
+                Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?
             ))
-            .unwrap(),
+            ?,
             JsonValue::String("936da01f-9abd-4d9d-80c7-02af85c822a8".into())
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3433_recursive_resolves_record() {
+    fn test_avro_3433_recursive_resolves_record() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -1840,7 +1863,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -1848,10 +1871,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer
             .resolve(&schema)
             .expect("Record definition defined in one field must be available in other field");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3433_recursive_resolves_array() {
+    fn test_avro_3433_recursive_resolves_array() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -1882,7 +1907,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -1896,10 +1921,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer_value
             .resolve(&schema)
             .expect("Record defined in array definition must be resolvable from map");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3433_recursive_resolves_map() {
+    fn test_avro_3433_recursive_resolves_map() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -1927,7 +1954,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -1941,10 +1968,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer_value
             .resolve(&schema)
             .expect("Record defined in record field must be resolvable from map field");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3433_recursive_resolves_record_wrapper() {
+    fn test_avro_3433_recursive_resolves_record_wrapper() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -1976,7 +2005,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![(
@@ -1986,10 +2015,12 @@ Field with name '"b"' is not a member of the map items"#,
         let outer_value =
             Value::Record(vec![("a".into(), inner_value1), ("b".into(), inner_value2)]);
         outer_value.resolve(&schema).expect("Record schema defined in field must be resolvable in Record schema defined in other field");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3433_recursive_resolves_map_and_array() {
+    fn test_avro_3433_recursive_resolves_map_and_array() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -2020,7 +2051,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -2034,10 +2065,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer_value
             .resolve(&schema)
             .expect("Record defined in map definition must be resolvable from array");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3433_recursive_resolves_union() {
+    fn test_avro_3433_recursive_resolves_union() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -2062,7 +2095,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
@@ -2077,10 +2110,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer2
             .resolve(&schema)
             .expect("Record definition defined in union must be resolved in other field");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3461_test_multi_level_resolve_outer_namespace() {
+    fn test_avro_3461_test_multi_level_resolve_outer_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -2122,7 +2157,7 @@ Field with name '"b"' is not a member of the map items"#,
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]);
         let middle_record_variation_1 = Value::Record(vec![(
             "middle_field_1".into(),
@@ -2163,10 +2198,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer_record_variation_3
             .resolve(&schema)
             .expect("Should be able to resolve value to the schema that is it's definition");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3461_test_multi_level_resolve_middle_namespace() {
+    fn test_avro_3461_test_multi_level_resolve_middle_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -2209,7 +2246,7 @@ Field with name '"b"' is not a member of the map items"#,
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
         let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]);
         let middle_record_variation_1 = Value::Record(vec![(
             "middle_field_1".into(),
@@ -2250,10 +2287,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer_record_variation_3
             .resolve(&schema)
             .expect("Should be able to resolve value to the schema that is it's definition");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3461_test_multi_level_resolve_inner_namespace() {
+    fn test_avro_3461_test_multi_level_resolve_inner_namespace() -> TestResult {
         let schema = r#"
         {
           "name": "record_name",
@@ -2297,7 +2336,7 @@ Field with name '"b"' is not a member of the map items"#,
           ]
         }
         "#;
-        let schema = Schema::parse_str(schema).unwrap();
+        let schema = Schema::parse_str(schema)?;
 
         let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]);
         let middle_record_variation_1 = Value::Record(vec![(
@@ -2339,10 +2378,12 @@ Field with name '"b"' is not a member of the map items"#,
         outer_record_variation_3
             .resolve(&schema)
             .expect("Should be able to resolve value to the schema that is it's definition");
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3460_validation_with_refs() {
+    fn test_avro_3460_validation_with_refs() -> TestResult {
         let schema = Schema::parse_str(
             r#"
         {
@@ -2367,7 +2408,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let inner_value_right = Value::Record(vec![("z".into(), Value::Int(3))]);
         let inner_value_wrong1 = Value::Record(vec![("z".into(), Value::Null)]);
@@ -2390,10 +2431,12 @@ Field with name '"b"' is not a member of the map items"#,
             !outer2.validate(&schema),
             "field b record is invalid against the schema"
         ); // this should pass, but doesn't
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3460_validation_with_refs_real_struct() {
+    fn test_avro_3460_validation_with_refs_real_struct() -> TestResult {
         use crate::ser::Serializer;
         use serde::Serialize;
 
@@ -2444,7 +2487,7 @@ Field with name '"b"' is not a member of the map items"#,
             ]
         }"#,
         )
-        .unwrap();
+        ?;
 
         let test_inner = TestInner { z: 3 };
         let test_outer1 = TestRefSchemaStruct1 {
@@ -2461,11 +2504,11 @@ Field with name '"b"' is not a member of the map items"#,
         };
 
         let mut ser = Serializer::default();
-        let test_outer1: Value = test_outer1.serialize(&mut ser).unwrap();
+        let test_outer1: Value = test_outer1.serialize(&mut ser)?;
         let mut ser = Serializer::default();
-        let test_outer2: Value = test_outer2.serialize(&mut ser).unwrap();
+        let test_outer2: Value = test_outer2.serialize(&mut ser)?;
         let mut ser = Serializer::default();
-        let test_outer3: Value = test_outer3.serialize(&mut ser).unwrap();
+        let test_outer3: Value = test_outer3.serialize(&mut ser)?;
 
         assert!(
             !test_outer1.validate(&schema),
@@ -2479,9 +2522,11 @@ Field with name '"b"' is not a member of the map items"#,
             !test_outer3.validate(&schema),
             "field b record is invalid against the schema"
         );
+
+        Ok(())
     }
 
-    fn avro_3674_with_or_without_namespace(with_namespace: bool) {
+    fn avro_3674_with_or_without_namespace(with_namespace: bool) -> TestResult {
         use crate::ser::Serializer;
         use serde::Serialize;
 
@@ -2523,7 +2568,7 @@ Field with name '"b"' is not a member of the map items"#,
             },
         );
 
-        let schema = Schema::parse_str(&schema_str).unwrap();
+        let schema = Schema::parse_str(&schema_str)?;
 
         #[derive(Serialize)]
         enum EnumType {
@@ -2552,25 +2597,27 @@ Field with name '"b"' is not a member of the map items"#,
         };
 
         let mut ser = Serializer::default();
-        let test_value: Value = msg.serialize(&mut ser).unwrap();
+        let test_value: Value = msg.serialize(&mut ser)?;
         assert!(test_value.validate(&schema), "test_value should validate");
         assert!(
             test_value.resolve(&schema).is_ok(),
             "test_value should resolve"
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3674_validate_no_namespace_resolution() {
-        avro_3674_with_or_without_namespace(false);
+    fn test_avro_3674_validate_no_namespace_resolution() -> TestResult {
+        avro_3674_with_or_without_namespace(false)
     }
 
     #[test]
-    fn test_avro_3674_validate_with_namespace_resolution() {
-        avro_3674_with_or_without_namespace(true);
+    fn test_avro_3674_validate_with_namespace_resolution() -> TestResult {
+        avro_3674_with_or_without_namespace(true)
     }
 
-    fn avro_3688_schema_resolution_panic(set_field_b: bool) {
+    fn avro_3688_schema_resolution_panic(set_field_b: bool) -> TestResult {
         use crate::ser::Serializer;
         use serde::{Deserialize, Serialize};
 
@@ -2617,7 +2664,7 @@ Field with name '"b"' is not a member of the map items"#,
             field_b: Option<Inner>,
         }
 
-        let schema = Schema::parse_str(schema_str).unwrap();
+        let schema = Schema::parse_str(schema_str)?;
 
         let msg = Message {
             field_a: Some(Inner {
@@ -2633,26 +2680,28 @@ Field with name '"b"' is not a member of the map items"#,
         };
 
         let mut ser = Serializer::default();
-        let test_value: Value = msg.serialize(&mut ser).unwrap();
+        let test_value: Value = msg.serialize(&mut ser)?;
         assert!(test_value.validate(&schema), "test_value should validate");
         assert!(
             test_value.resolve(&schema).is_ok(),
             "test_value should resolve"
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3688_field_b_not_set() {
-        avro_3688_schema_resolution_panic(false);
+    fn test_avro_3688_field_b_not_set()-> TestResult  {
+        avro_3688_schema_resolution_panic(false)
     }
 
     #[test]
-    fn test_avro_3688_field_b_set() {
-        avro_3688_schema_resolution_panic(true);
+    fn test_avro_3688_field_b_set()-> TestResult  {
+        avro_3688_schema_resolution_panic(true)
     }
 
     #[test]
-    fn test_avro_3764_use_resolve_schemata() {
+    fn test_avro_3764_use_resolve_schemata() -> TestResult  {
         let referenced_schema =
             r#"{"name": "enumForReference", "type": "enum", "symbols": ["A", "B"]}"#;
         let main_schema = r#"{"name": "recordWithReference", "type": "record", "fields": [{"name": "reference", "type": "enumForReference"}]}"#;
@@ -2663,19 +2712,18 @@ Field with name '"b"' is not a member of the map items"#,
                 "reference": "A"
             }
         "#,
-        )
-        .unwrap();
+        )?;
 
         let avro_value = Value::from(value);
 
-        let schemas = Schema::parse_list(&[main_schema, referenced_schema]).unwrap();
+        let schemas = Schema::parse_list(&[main_schema, referenced_schema])?;
 
         let main_schema = schemas.get(0).unwrap();
         let schemata: Vec<_> = schemas.iter().skip(1).collect();
 
         let resolve_result = avro_value
             .clone()
-            .resolve_schemata(main_schema, schemata.clone());
+            .resolve_schemata(main_schema, schemata);
 
         assert!(
             resolve_result.is_ok(),
@@ -2689,5 +2737,7 @@ Field with name '"b"' is not a member of the map items"#,
             "result of resolving without schemata should be err, got: {:?}",
             resolve_result
         );
+
+        Ok(())
     }
 }
diff --git a/lang/rust/avro/src/util.rs b/lang/rust/avro/src/util.rs
index d94acce7a..5ce901ed4 100644
--- a/lang/rust/avro/src/util.rs
+++ b/lang/rust/avro/src/util.rs
@@ -188,6 +188,7 @@ pub(crate) fn is_human_readable() -> bool {
 mod tests {
     use super::*;
     use pretty_assertions::assert_eq;
+    use apache_avro_test_helper::TestResult;
 
     #[test]
     fn test_zigzag() {
@@ -280,8 +281,10 @@ mod tests {
     }
 
     #[test]
-    fn test_safe_len() {
-        assert_eq!(42usize, safe_len(42usize).unwrap());
+    fn test_safe_len() -> TestResult {
+        assert_eq!(42usize, safe_len(42usize)?);
         assert!(safe_len(1024 * 1024 * 1024).is_err());
+
+        Ok(())
     }
 }
diff --git a/lang/rust/avro/src/writer.rs b/lang/rust/avro/src/writer.rs
index 58d13d40f..83e863455 100644
--- a/lang/rust/avro/src/writer.rs
+++ b/lang/rust/avro/src/writer.rs
@@ -639,6 +639,8 @@ mod tests {
     use pretty_assertions::assert_eq;
     use serde::{Deserialize, Serialize};
 
+    use apache_avro_test_helper::TestResult;
+
     const AVRO_OBJECT_HEADER_LEN: usize = AVRO_OBJECT_HEADER.len();
 
     const SCHEMA: &str = r#"
@@ -661,8 +663,8 @@ mod tests {
     const UNION_SCHEMA: &str = r#"["null", "long"]"#;
 
     #[test]
-    fn test_to_avro_datum() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_to_avro_datum() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut record = Record::new(&schema).unwrap();
         record.put("a", 27i64);
         record.put("b", "foo");
@@ -672,33 +674,37 @@ mod tests {
         zig_i64(3, &mut expected);
         expected.extend(vec![b'f', b'o', b'o'].into_iter());
 
-        assert_eq!(to_avro_datum(&schema, record).unwrap(), expected);
+        assert_eq!(to_avro_datum(&schema, record)?, expected);
+
+        Ok(())
     }
 
     #[test]
-    fn test_union_not_null() {
-        let schema = Schema::parse_str(UNION_SCHEMA).unwrap();
+    fn test_union_not_null() -> TestResult {
+        let schema = Schema::parse_str(UNION_SCHEMA)?;
         let union = Value::Union(1, Box::new(Value::Long(3)));
 
         let mut expected = Vec::new();
         zig_i64(1, &mut expected);
         zig_i64(3, &mut expected);
 
-        assert_eq!(to_avro_datum(&schema, union).unwrap(), expected);
+        assert_eq!(to_avro_datum(&schema, union)?, expected);
+
+        Ok(())
     }
 
     #[test]
-    fn test_union_null() {
-        let schema = Schema::parse_str(UNION_SCHEMA).unwrap();
+    fn test_union_null() -> TestResult {
+        let schema = Schema::parse_str(UNION_SCHEMA)?;
         let union = Value::Union(0, Box::new(Value::Null));
 
         let mut expected = Vec::new();
         zig_i64(0, &mut expected);
 
-        assert_eq!(to_avro_datum(&schema, union).unwrap(), expected);
-    }
+        assert_eq!(to_avro_datum(&schema, union)?, expected);
 
-    type TestResult<T> = anyhow::Result<T, Box<dyn std::error::Error>>;
+        Ok(())
+    }
 
     fn logical_type_test<T: Into<Value> + Clone>(
         schema_str: &'static str,
@@ -708,7 +714,7 @@ mod tests {
 
         raw_schema: &Schema,
         raw_value: T,
-    ) -> TestResult<()> {
+    ) -> TestResult {
         let schema = Schema::parse_str(schema_str)?;
         assert_eq!(&schema, expected_schema);
         // The serialized format should be the same as the schema.
@@ -718,13 +724,13 @@ mod tests {
 
         // Should deserialize from the schema into the logical type.
         let mut r = ser.as_slice();
-        let de = crate::from_avro_datum(&schema, &mut r, None).unwrap();
+        let de = crate::from_avro_datum(&schema, &mut r, None)?;
         assert_eq!(de, value);
         Ok(())
     }
 
     #[test]
-    fn date() -> TestResult<()> {
+    fn date() -> TestResult {
         logical_type_test(
             r#"{"type": "int", "logicalType": "date"}"#,
             &Schema::Date,
@@ -735,7 +741,7 @@ mod tests {
     }
 
     #[test]
-    fn time_millis() -> TestResult<()> {
+    fn time_millis() -> TestResult {
         logical_type_test(
             r#"{"type": "int", "logicalType": "time-millis"}"#,
             &Schema::TimeMillis,
@@ -746,7 +752,7 @@ mod tests {
     }
 
     #[test]
-    fn time_micros() -> TestResult<()> {
+    fn time_micros() -> TestResult {
         logical_type_test(
             r#"{"type": "long", "logicalType": "time-micros"}"#,
             &Schema::TimeMicros,
@@ -757,7 +763,7 @@ mod tests {
     }
 
     #[test]
-    fn timestamp_millis() -> TestResult<()> {
+    fn timestamp_millis() -> TestResult {
         logical_type_test(
             r#"{"type": "long", "logicalType": "timestamp-millis"}"#,
             &Schema::TimestampMillis,
@@ -768,7 +774,7 @@ mod tests {
     }
 
     #[test]
-    fn timestamp_micros() -> TestResult<()> {
+    fn timestamp_micros() -> TestResult {
         logical_type_test(
             r#"{"type": "long", "logicalType": "timestamp-micros"}"#,
             &Schema::TimestampMicros,
@@ -779,10 +785,10 @@ mod tests {
     }
 
     #[test]
-    fn decimal_fixed() -> TestResult<()> {
+    fn decimal_fixed() -> TestResult {
         let size = 30;
         let inner = Schema::Fixed(FixedSchema {
-            name: Name::new("decimal").unwrap(),
+            name: Name::new("decimal")?,
             aliases: None,
             doc: None,
             size,
@@ -803,7 +809,7 @@ mod tests {
     }
 
     #[test]
-    fn decimal_bytes() -> TestResult<()> {
+    fn decimal_bytes() -> TestResult {
         let inner = Schema::Bytes;
         let value = vec![0u8; 10];
         logical_type_test(
@@ -820,9 +826,9 @@ mod tests {
     }
 
     #[test]
-    fn duration() -> TestResult<()> {
+    fn duration() -> TestResult {
         let inner = Schema::Fixed(FixedSchema {
-            name: Name::new("duration").unwrap(),
+            name: Name::new("duration")?,
             aliases: None,
             doc: None,
             size: 12,
@@ -843,18 +849,18 @@ mod tests {
     }
 
     #[test]
-    fn test_writer_append() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_writer_append() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
         let mut record = Record::new(&schema).unwrap();
         record.put("a", 27i64);
         record.put("b", "foo");
 
-        let n1 = writer.append(record.clone()).unwrap();
-        let n2 = writer.append(record.clone()).unwrap();
-        let n3 = writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        let n1 = writer.append(record.clone())?;
+        let n2 = writer.append(record.clone())?;
+        let n3 = writer.flush()?;
+        let result = writer.into_inner()?;
 
         assert_eq!(n1 + n2 + n3, result.len());
 
@@ -872,11 +878,13 @@ mod tests {
             &result[last_data_byte - data.len()..last_data_byte],
             data.as_slice()
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_writer_extend() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_writer_extend() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
         let mut record = Record::new(&schema).unwrap();
@@ -885,9 +893,9 @@ mod tests {
         let record_copy = record.clone();
         let records = vec![record, record_copy];
 
-        let n1 = writer.extend(records.into_iter()).unwrap();
-        let n2 = writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        let n1 = writer.extend(records.into_iter())?;
+        let n2 = writer.flush()?;
+        let result = writer.into_inner()?;
 
         assert_eq!(n1 + n2, result.len());
 
@@ -905,6 +913,8 @@ mod tests {
             &result[last_data_byte - data.len()..last_data_byte],
             data.as_slice()
         );
+
+        Ok(())
     }
 
     #[derive(Debug, Clone, Deserialize, Serialize)]
@@ -914,8 +924,8 @@ mod tests {
     }
 
     #[test]
-    fn test_writer_append_ser() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_writer_append_ser() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
         let record = TestSerdeSerialize {
@@ -923,9 +933,9 @@ mod tests {
             b: "foo".to_owned(),
         };
 
-        let n1 = writer.append_ser(record).unwrap();
-        let n2 = writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        let n1 = writer.append_ser(record)?;
+        let n2 = writer.flush()?;
+        let result = writer.into_inner()?;
 
         assert_eq!(n1 + n2, result.len());
 
@@ -942,11 +952,13 @@ mod tests {
             &result[last_data_byte - data.len()..last_data_byte],
             data.as_slice()
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_writer_extend_ser() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_writer_extend_ser() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
         let record = TestSerdeSerialize {
@@ -956,9 +968,9 @@ mod tests {
         let record_copy = record.clone();
         let records = vec![record, record_copy];
 
-        let n1 = writer.extend_ser(records.into_iter()).unwrap();
-        let n2 = writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        let n1 = writer.extend_ser(records.into_iter())?;
+        let n2 = writer.flush()?;
+        let result = writer.into_inner()?;
 
         assert_eq!(n1 + n2, result.len());
 
@@ -976,6 +988,8 @@ mod tests {
             &result[last_data_byte - data.len()..last_data_byte],
             data.as_slice()
         );
+
+        Ok(())
     }
 
     fn make_writer_with_codec(schema: &Schema) -> Writer<'_, Vec<u8>> {
@@ -991,15 +1005,15 @@ mod tests {
             .build()
     }
 
-    fn check_writer(mut writer: Writer<'_, Vec<u8>>, schema: &Schema) {
+    fn check_writer(mut writer: Writer<'_, Vec<u8>>, schema: &Schema) -> TestResult {
         let mut record = Record::new(schema).unwrap();
         record.put("a", 27i64);
         record.put("b", "foo");
 
-        let n1 = writer.append(record.clone()).unwrap();
-        let n2 = writer.append(record.clone()).unwrap();
-        let n3 = writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        let n1 = writer.append(record.clone())?;
+        let n2 = writer.append(record.clone())?;
+        let n3 = writer.flush()?;
+        let result = writer.into_inner()?;
 
         assert_eq!(n1 + n2 + n3, result.len());
 
@@ -1008,7 +1022,7 @@ mod tests {
         zig_i64(3, &mut data);
         data.extend(b"foo");
         data.extend(data.clone());
-        Codec::Deflate.compress(&mut data).unwrap();
+        Codec::Deflate.compress(&mut data)?;
 
         // starts with magic
         assert_eq!(&result[..AVRO_OBJECT_HEADER_LEN], AVRO_OBJECT_HEADER);
@@ -1018,24 +1032,26 @@ mod tests {
             &result[last_data_byte - data.len()..last_data_byte],
             data.as_slice()
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_writer_with_codec() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_writer_with_codec() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let writer = make_writer_with_codec(&schema);
-        check_writer(writer, &schema);
+        check_writer(writer, &schema)
     }
 
     #[test]
-    fn test_writer_with_builder() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_writer_with_builder() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let writer = make_writer_with_builder(&schema);
-        check_writer(writer, &schema);
+        check_writer(writer, &schema)
     }
 
     #[test]
-    fn test_logical_writer() {
+    fn test_logical_writer() -> TestResult {
         const LOGICAL_TYPE_SCHEMA: &str = r#"
         {
           "type": "record",
@@ -1055,7 +1071,7 @@ mod tests {
         }
         "#;
         let codec = Codec::Deflate;
-        let schema = Schema::parse_str(LOGICAL_TYPE_SCHEMA).unwrap();
+        let schema = Schema::parse_str(LOGICAL_TYPE_SCHEMA)?;
         let mut writer = Writer::builder()
             .schema(&schema)
             .codec(codec)
@@ -1071,10 +1087,10 @@ mod tests {
         let mut record2 = Record::new(&schema).unwrap();
         record2.put("a", Value::Union(0, Box::new(Value::Null)));
 
-        let n1 = writer.append(record1).unwrap();
-        let n2 = writer.append(record2).unwrap();
-        let n3 = writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        let n1 = writer.append(record1)?;
+        let n2 = writer.append(record2)?;
+        let n3 = writer.flush()?;
+        let result = writer.into_inner()?;
 
         assert_eq!(n1 + n2 + n3, result.len());
 
@@ -1085,7 +1101,7 @@ mod tests {
 
         // byte indicating null
         zig_i64(0, &mut data);
-        codec.compress(&mut data).unwrap();
+        codec.compress(&mut data)?;
 
         // starts with magic
         assert_eq!(&result[..AVRO_OBJECT_HEADER_LEN], AVRO_OBJECT_HEADER);
@@ -1095,47 +1111,43 @@ mod tests {
             &result[last_data_byte - data.len()..last_data_byte],
             data.as_slice()
         );
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3405_writer_add_metadata_success() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_avro_3405_writer_add_metadata_success() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
-        writer
-            .add_user_metadata("stringKey".to_string(), String::from("stringValue"))
-            .unwrap();
-        writer
-            .add_user_metadata("strKey".to_string(), "strValue")
-            .unwrap();
-        writer
-            .add_user_metadata("bytesKey".to_string(), b"bytesValue")
-            .unwrap();
-        writer
-            .add_user_metadata("vecKey".to_string(), vec![1, 2, 3])
-            .unwrap();
+        writer.add_user_metadata("stringKey".to_string(), String::from("stringValue"))?;
+        writer.add_user_metadata("strKey".to_string(), "strValue")?;
+        writer.add_user_metadata("bytesKey".to_string(), b"bytesValue")?;
+        writer.add_user_metadata("vecKey".to_string(), vec![1, 2, 3])?;
 
         let mut record = Record::new(&schema).unwrap();
         record.put("a", 27i64);
         record.put("b", "foo");
 
-        writer.append(record.clone()).unwrap();
-        writer.append(record.clone()).unwrap();
-        writer.flush().unwrap();
-        let result = writer.into_inner().unwrap();
+        writer.append(record.clone())?;
+        writer.append(record.clone())?;
+        writer.flush()?;
+        let result = writer.into_inner()?;
 
         assert_eq!(result.len(), 260);
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3405_writer_add_metadata_failure() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_avro_3405_writer_add_metadata_failure() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
         let mut record = Record::new(&schema).unwrap();
         record.put("a", 27i64);
         record.put("b", "foo");
-        writer.append(record.clone()).unwrap();
+        writer.append(record.clone())?;
 
         match writer.add_user_metadata("stringKey".to_string(), String::from("value2")) {
             Err(e @ Error::FileHeaderAlreadyWritten) => {
@@ -1144,11 +1156,13 @@ mod tests {
             Err(e) => panic!("Unexpected error occurred while writing user metadata: {e:?}"),
             Ok(_) => panic!("Expected an error that metadata cannot be added after adding data"),
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3405_writer_add_metadata_reserved_prefix_failure() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_avro_3405_writer_add_metadata_reserved_prefix_failure() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
         let mut writer = Writer::new(&schema, Vec::new());
 
         let key = "avro.stringKey".to_string();
@@ -1161,11 +1175,13 @@ mod tests {
             ),
             Ok(_) => panic!("Expected an error that the metadata key cannot be prefixed with 'avro.'"),
         }
+
+        Ok(())
     }
 
     #[test]
-    fn test_avro_3405_writer_add_metadata_with_builder_api_success() {
-        let schema = Schema::parse_str(SCHEMA).unwrap();
+    fn test_avro_3405_writer_add_metadata_with_builder_api_success() -> TestResult {
+        let schema = Schema::parse_str(SCHEMA)?;
 
         let mut user_meta_data: HashMap<String, Value> = HashMap::new();
         user_meta_data.insert(
@@ -1182,6 +1198,8 @@ mod tests {
             .build();
 
         assert_eq!(writer.user_metadata, user_meta_data);
+
+        Ok(())
     }
 
     #[derive(Serialize, Clone)]
@@ -1234,7 +1252,7 @@ mod tests {
     }
 
     #[test]
-    fn test_single_object_writer() {
+    fn test_single_object_writer() -> TestResult {
         let mut buf: Vec<u8> = Vec::new();
         let obj = TestSingleObjectWriter {
             a: 300,
@@ -1268,11 +1286,13 @@ mod tests {
             &mut msg_binary,
         )
         .expect("encode should have failed by here as a dependency of any writing");
-        assert_eq!(&buf[10..], &msg_binary[..])
+        assert_eq!(&buf[10..], &msg_binary[..]);
+
+        Ok(())
     }
 
     #[test]
-    fn test_writer_parity() {
+    fn test_writer_parity() -> TestResult {
         let obj1 = TestSingleObjectWriter {
             a: 300,
             b: 34.555,
@@ -1302,5 +1322,7 @@ mod tests {
             .expect("Serialization expected");
         assert_eq!(buf1, buf2);
         assert_eq!(buf1, buf3);
+
+        Ok(())
     }
 }
diff --git a/lang/rust/avro/tests/append_to_existing.rs b/lang/rust/avro/tests/append_to_existing.rs
index 7b3874746..2ea59d95c 100644
--- a/lang/rust/avro/tests/append_to_existing.rs
+++ b/lang/rust/avro/tests/append_to_existing.rs
@@ -20,9 +20,10 @@ use apache_avro::{
     types::{Record, Value},
     AvroResult, Reader, Schema, Writer,
 };
+use apache_avro_test_helper::TestResult;
 
 #[test]
-fn avro_3630_append_to_an_existing_file() {
+fn avro_3630_append_to_an_existing_file() -> TestResult {
     let schema_str = r#"
             {
                 "type": "record",
@@ -53,6 +54,8 @@ fn avro_3630_append_to_an_existing_file() {
         check(value, i);
         i += 1
     }
+
+    Ok(())
 }
 
 /// Simulates reading from a pre-existing .avro file and returns its bytes
diff --git a/lang/rust/avro/tests/io.rs b/lang/rust/avro/tests/io.rs
index 9d3dc7b79..7c3d5e961 100644
--- a/lang/rust/avro/tests/io.rs
+++ b/lang/rust/avro/tests/io.rs
@@ -20,6 +20,7 @@ use apache_avro::{from_avro_datum, to_avro_datum, types::Value, Error, Schema};
 use lazy_static::lazy_static;
 use pretty_assertions::assert_eq;
 use std::io::Cursor;
+use apache_avro_test_helper::TestResult;
 
 lazy_static! {
     static ref SCHEMAS_TO_VALIDATE: Vec<(&'static str, Value)> = vec![
@@ -99,44 +100,52 @@ lazy_static! {
 }
 
 #[test]
-fn test_validate() {
+fn test_validate() -> TestResult {
     for (raw_schema, value) in SCHEMAS_TO_VALIDATE.iter() {
-        let schema = Schema::parse_str(raw_schema).unwrap();
+        let schema = Schema::parse_str(raw_schema)?;
         assert!(
             value.validate(&schema),
             "value {value:?} does not validate schema: {raw_schema}"
         );
     }
+
+    Ok(())
 }
 
 #[test]
-fn test_round_trip() {
+fn test_round_trip() -> TestResult {
     for (raw_schema, value) in SCHEMAS_TO_VALIDATE.iter() {
-        let schema = Schema::parse_str(raw_schema).unwrap();
+        let schema = Schema::parse_str(raw_schema)?;
         let encoded = to_avro_datum(&schema, value.clone()).unwrap();
         let decoded = from_avro_datum(&schema, &mut Cursor::new(encoded), None).unwrap();
         assert_eq!(value, &decoded);
     }
+
+    Ok(())
 }
 
 #[test]
-fn test_binary_int_encoding() {
+fn test_binary_int_encoding() -> TestResult {
     for (number, hex_encoding) in BINARY_ENCODINGS.iter() {
-        let encoded = to_avro_datum(&Schema::Int, Value::Int(*number as i32)).unwrap();
+        let encoded = to_avro_datum(&Schema::Int, Value::Int(*number as i32))?;
         assert_eq!(&encoded, hex_encoding);
     }
+
+    Ok(())
 }
 
 #[test]
-fn test_binary_long_encoding() {
+fn test_binary_long_encoding() -> TestResult {
     for (number, hex_encoding) in BINARY_ENCODINGS.iter() {
-        let encoded = to_avro_datum(&Schema::Long, Value::Long(*number)).unwrap();
+        let encoded = to_avro_datum(&Schema::Long, Value::Long(*number))?;
         assert_eq!(&encoded, hex_encoding);
     }
+
+    Ok(())
 }
 
 #[test]
-fn test_schema_promotion() {
+fn test_schema_promotion() -> TestResult {
     // Each schema is present in order of promotion (int -> long, long -> float, float -> double)
     // Each value represents the expected decoded value when promoting a value previously encoded with a promotable schema
     let promotable_schemas = vec![r#""int""#, r#""long""#, r#""float""#, r#""double""#];
@@ -147,11 +156,11 @@ fn test_schema_promotion() {
         Value::Double(219.0),
     ];
     for (i, writer_raw_schema) in promotable_schemas.iter().enumerate() {
-        let writer_schema = Schema::parse_str(writer_raw_schema).unwrap();
+        let writer_schema = Schema::parse_str(writer_raw_schema)?;
         let original_value = &promotable_values[i];
         for (j, reader_raw_schema) in promotable_schemas.iter().enumerate().skip(i + 1) {
-            let reader_schema = Schema::parse_str(reader_raw_schema).unwrap();
-            let encoded = to_avro_datum(&writer_schema, original_value.clone()).unwrap();
+            let reader_schema = Schema::parse_str(reader_raw_schema)?;
+            let encoded = to_avro_datum(&writer_schema, original_value.clone())?;
             let decoded = from_avro_datum(
                 &writer_schema,
                 &mut Cursor::new(encoded),
@@ -163,28 +172,30 @@ fn test_schema_promotion() {
             assert_eq!(decoded, promotable_values[j]);
         }
     }
+
+    Ok(())
 }
 
 #[test]
-fn test_unknown_symbol() {
+fn test_unknown_symbol() -> TestResult {
     let writer_schema =
-        Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["FOO", "BAR"]}"#)
-            .unwrap();
+        Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["FOO", "BAR"]}"#)?;
     let reader_schema =
-        Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["BAR", "BAZ"]}"#)
-            .unwrap();
+        Schema::parse_str(r#"{"type": "enum", "name": "Test", "symbols": ["BAR", "BAZ"]}"#)?;
     let original_value = Value::Enum(0, "FOO".to_string());
-    let encoded = to_avro_datum(&writer_schema, original_value).unwrap();
+    let encoded = to_avro_datum(&writer_schema, original_value)?;
     let decoded = from_avro_datum(
         &writer_schema,
         &mut Cursor::new(encoded),
         Some(&reader_schema),
     );
     assert!(decoded.is_err());
+
+    Ok(())
 }
 
 #[test]
-fn test_default_value() {
+fn test_default_value() -> TestResult {
     for (field_type, default_json, default_datum) in DEFAULT_VALUE_EXAMPLES.iter() {
         let reader_schema = Schema::parse_str(&format!(
             r#"{{
@@ -194,26 +205,26 @@ fn test_default_value() {
                     {{"name": "H", "type": {field_type}, "default": {default_json}}}
                 ]
             }}"#
-        ))
-        .unwrap();
+        ))?;
         let datum_to_read = Value::Record(vec![("H".to_string(), default_datum.clone())]);
-        let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap();
+        let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?;
         let datum_read = from_avro_datum(
             &LONG_RECORD_SCHEMA,
             &mut Cursor::new(encoded),
             Some(&reader_schema),
-        )
-        .unwrap();
+        )?;
         assert_eq!(
             datum_read, datum_to_read,
             "{} -> {}",
             *field_type, *default_json
         );
     }
+
+    Ok(())
 }
 
 #[test]
-fn test_no_default_value() {
+fn test_no_default_value() -> TestResult {
     let reader_schema = Schema::parse_str(
         r#"{
             "type": "record",
@@ -222,19 +233,20 @@ fn test_no_default_value() {
                 {"name": "H", "type": "int"}
             ]
         }"#,
-    )
-    .unwrap();
-    let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap();
+    )?;
+    let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?;
     let result = from_avro_datum(
         &LONG_RECORD_SCHEMA,
         &mut Cursor::new(encoded),
         Some(&reader_schema),
     );
     assert!(result.is_err());
+
+    Ok(())
 }
 
 #[test]
-fn test_projection() {
+fn test_projection() -> TestResult {
     let reader_schema = Schema::parse_str(
         r#"
         {
@@ -246,24 +258,24 @@ fn test_projection() {
             ]
         }
     "#,
-    )
-    .unwrap();
+    )?;
     let datum_to_read = Value::Record(vec![
         ("E".to_string(), Value::Int(5)),
         ("F".to_string(), Value::Int(6)),
     ]);
-    let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap();
+    let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?;
     let datum_read = from_avro_datum(
         &LONG_RECORD_SCHEMA,
         &mut Cursor::new(encoded),
         Some(&reader_schema),
-    )
-    .unwrap();
+    )?;
     assert_eq!(datum_to_read, datum_read);
+
+    Ok(())
 }
 
 #[test]
-fn test_field_order() {
+fn test_field_order() -> TestResult {
     let reader_schema = Schema::parse_str(
         r#"
         {
@@ -275,20 +287,20 @@ fn test_field_order() {
             ]
         }
     "#,
-    )
-    .unwrap();
+    )?;
     let datum_to_read = Value::Record(vec![
         ("F".to_string(), Value::Int(6)),
         ("E".to_string(), Value::Int(5)),
     ]);
-    let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone()).unwrap();
+    let encoded = to_avro_datum(&LONG_RECORD_SCHEMA, LONG_RECORD_DATUM.clone())?;
     let datum_read = from_avro_datum(
         &LONG_RECORD_SCHEMA,
         &mut Cursor::new(encoded),
         Some(&reader_schema),
-    )
-    .unwrap();
+    )?;
     assert_eq!(datum_to_read, datum_read);
+
+    Ok(())
 }
 
 #[test]
@@ -304,8 +316,7 @@ fn test_type_exception() -> Result<(), String> {
              ]
         }
     "#,
-    )
-    .unwrap();
+    ).unwrap();
     let datum_to_write = Value::Record(vec![
         ("E".to_string(), Value::Int(5)),
         ("F".to_string(), Value::String(String::from("Bad"))),
diff --git a/lang/rust/avro/tests/schema.rs b/lang/rust/avro/tests/schema.rs
index 5018dc5dd..46292daea 100644
--- a/lang/rust/avro/tests/schema.rs
+++ b/lang/rust/avro/tests/schema.rs
@@ -21,7 +21,7 @@ use apache_avro::{
     types::{Record, Value},
     Codec, Error, Reader, Schema, Writer,
 };
-use apache_avro_test_helper::init;
+use apache_avro_test_helper::{init, TestResult};
 use lazy_static::lazy_static;
 
 const PRIMITIVE_EXAMPLES: &[(&str, bool)] = &[
@@ -612,7 +612,7 @@ lazy_static! {
 }
 
 #[test]
-fn test_correct_recursive_extraction() {
+fn test_correct_recursive_extraction() -> TestResult {
     init();
     let raw_outer_schema = r#"{
         "type": "record",
@@ -633,7 +633,7 @@ fn test_correct_recursive_extraction() {
             }
         ]
     }"#;
-    let outer_schema = Schema::parse_str(raw_outer_schema).unwrap();
+    let outer_schema = Schema::parse_str(raw_outer_schema)?;
     if let Schema::Record(RecordSchema {
         fields: outer_fields,
         ..
@@ -658,10 +658,12 @@ fn test_correct_recursive_extraction() {
     } else {
         panic!("outer schema {outer_schema:?} should have been a record")
     }
+
+    Ok(())
 }
 
 #[test]
-fn test_parse() {
+fn test_parse() -> TestResult {
     init();
     for (raw_schema, valid) in EXAMPLES.iter() {
         let schema = Schema::parse_str(raw_schema);
@@ -677,36 +679,39 @@ fn test_parse() {
             )
         }
     }
+    Ok(())
 }
 
 #[test]
 /// Test that the string generated by an Avro Schema object is, in fact, a valid Avro schema.
-fn test_valid_cast_to_string_after_parse() {
+fn test_valid_cast_to_string_after_parse() -> TestResult {
     init();
     for (raw_schema, _) in VALID_EXAMPLES.iter() {
-        let schema = Schema::parse_str(raw_schema).unwrap();
-        Schema::parse_str(schema.canonical_form().as_str()).unwrap();
+        let schema = Schema::parse_str(raw_schema)?;
+        Schema::parse_str(schema.canonical_form().as_str())?;
     }
+    Ok(())
 }
 
 #[test]
 /// 1. Given a string, parse it to get Avro schema "original".
 /// 2. Serialize "original" to a string and parse that string to generate Avro schema "round trip".
 /// 3. Ensure "original" and "round trip" schemas are equivalent.
-fn test_equivalence_after_round_trip() {
+fn test_equivalence_after_round_trip() -> TestResult {
     init();
     for (raw_schema, _) in VALID_EXAMPLES.iter() {
-        let original_schema = Schema::parse_str(raw_schema).unwrap();
+        let original_schema = Schema::parse_str(raw_schema)?;
         let round_trip_schema =
-            Schema::parse_str(original_schema.canonical_form().as_str()).unwrap();
+            Schema::parse_str(original_schema.canonical_form().as_str())?;
         assert_eq!(original_schema, round_trip_schema);
     }
+    Ok(())
 }
 
 #[test]
 /// Test that a list of schemas whose definitions do not depend on each other produces the same
 /// result as parsing each element of the list individually
-fn test_parse_list_without_cross_deps() {
+fn test_parse_list_without_cross_deps() -> TestResult {
     init();
     let schema_str_1 = r#"{
         "name": "A",
@@ -721,12 +726,13 @@ fn test_parse_list_without_cross_deps() {
         "size": 16
     }"#;
     let schema_strs = [schema_str_1, schema_str_2];
-    let schemas = Schema::parse_list(&schema_strs).expect("Test failed");
+    let schemas = Schema::parse_list(&schema_strs)?;
 
     for schema_str in &schema_strs {
-        let parsed = Schema::parse_str(schema_str).expect("Test failed");
+        let parsed = Schema::parse_str(schema_str)?;
         assert!(schemas.contains(&parsed));
     }
+    Ok(())
 }
 
 #[test]
@@ -734,7 +740,7 @@ fn test_parse_list_without_cross_deps() {
 /// perform the necessary schema composition. This should work regardless of the order in which
 /// the schemas are input.
 /// However, the output order is guaranteed to be the same as the input order.
-fn test_parse_list_with_cross_deps_basic() {
+fn test_parse_list_with_cross_deps_basic() -> TestResult {
     init();
     let schema_a_str = r#"{
         "name": "A",
@@ -753,15 +759,16 @@ fn test_parse_list_with_cross_deps_basic() {
 
     let schema_strs_first = [schema_a_str, schema_b_str];
     let schema_strs_second = [schema_b_str, schema_a_str];
-    let schemas_first = Schema::parse_list(&schema_strs_first).expect("Test failed");
-    let schemas_second = Schema::parse_list(&schema_strs_second).expect("Test failed");
+    let schemas_first = Schema::parse_list(&schema_strs_first)?;
+    let schemas_second = Schema::parse_list(&schema_strs_second)?;
 
     assert_eq!(schemas_first[0], schemas_second[1]);
     assert_eq!(schemas_first[1], schemas_second[0]);
+    Ok(())
 }
 
 #[test]
-fn test_parse_list_recursive_type() {
+fn test_parse_list_recursive_type() -> TestResult {
     init();
     let schema_str_1 = r#"{
         "name": "A",
@@ -781,13 +788,14 @@ fn test_parse_list_recursive_type() {
     }"#;
     let schema_strs_first = [schema_str_1, schema_str_2];
     let schema_strs_second = [schema_str_2, schema_str_1];
-    let _ = Schema::parse_list(&schema_strs_first).expect("Test failed");
-    let _ = Schema::parse_list(&schema_strs_second).expect("Test failed");
+    let _ = Schema::parse_list(&schema_strs_first)?;
+    let _ = Schema::parse_list(&schema_strs_second)?;
+    Ok(())
 }
 
 #[test]
 /// Test that schema composition resolves namespaces.
-fn test_parse_list_with_cross_deps_and_namespaces() {
+fn test_parse_list_with_cross_deps_and_namespaces() -> TestResult {
     init();
     let schema_a_str = r#"{
         "name": "A",
@@ -805,16 +813,18 @@ fn test_parse_list_with_cross_deps_and_namespaces() {
         ]
     }"#;
 
-    let schemas_first = Schema::parse_list(&[schema_a_str, schema_b_str]).expect("Test failed");
-    let schemas_second = Schema::parse_list(&[schema_b_str, schema_a_str]).expect("Test failed");
+    let schemas_first = Schema::parse_list(&[schema_a_str, schema_b_str])?;
+    let schemas_second = Schema::parse_list(&[schema_b_str, schema_a_str])?;
 
     assert_eq!(schemas_first[0], schemas_second[1]);
     assert_eq!(schemas_first[1], schemas_second[0]);
+
+    Ok(())
 }
 
 #[test]
 /// Test that schema composition fails on namespace errors.
-fn test_parse_list_with_cross_deps_and_namespaces_error() {
+fn test_parse_list_with_cross_deps_and_namespaces_error() -> TestResult {
     init();
     let schema_str_1 = r#"{
         "name": "A",
@@ -836,12 +846,14 @@ fn test_parse_list_with_cross_deps_and_namespaces_error() {
     let schema_strs_second = [schema_str_2, schema_str_1];
     let _ = Schema::parse_list(&schema_strs_first).expect_err("Test failed");
     let _ = Schema::parse_list(&schema_strs_second).expect_err("Test failed");
+
+    Ok(())
 }
 
 #[test]
 // <https://issues.apache.org/jira/browse/AVRO-3216>
 // test that field's RecordSchema could be referenced by a following field by full name
-fn test_parse_reused_record_schema_by_fullname() {
+fn test_parse_reused_record_schema_by_fullname() -> TestResult {
     init();
     let schema_str = r#"
         {
@@ -879,7 +891,7 @@ fn test_parse_reused_record_schema_by_fullname() {
 
     let schema = Schema::parse_str(schema_str);
     assert!(schema.is_ok());
-    match schema.unwrap() {
+    match schema? {
         Schema::Record(RecordSchema {
             ref name,
             aliases: _,
@@ -914,6 +926,8 @@ fn test_parse_reused_record_schema_by_fullname() {
         }
         unexpected => unreachable!("Unexpected schema type: {:?}", unexpected),
     }
+
+    Ok(())
 }
 
 /// Return all permutations of an input slice
@@ -956,7 +970,7 @@ fn permutation_indices(indices: Vec<usize>) -> Vec<Vec<usize>> {
 #[test]
 /// Test that a type that depends on more than one other type is parsed correctly when all
 /// definitions are passed in as a list. This should work regardless of the ordering of the list.
-fn test_parse_list_multiple_dependencies() {
+fn test_parse_list_multiple_dependencies() -> TestResult {
     init();
     let schema_a_str = r#"{
         "name": "A",
@@ -979,22 +993,23 @@ fn test_parse_list_multiple_dependencies() {
     }"#;
 
     let parsed =
-        Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str]).expect("Test failed");
+        Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str])?;
     let schema_strs = vec![schema_a_str, schema_b_str, schema_c_str];
     for schema_str_perm in permutations(&schema_strs) {
         let schema_str_perm: Vec<&str> = schema_str_perm.iter().map(|s| **s).collect();
-        let schemas = Schema::parse_list(&schema_str_perm).expect("Test failed");
+        let schemas = Schema::parse_list(&schema_str_perm)?;
         assert_eq!(schemas.len(), 3);
         for parsed_schema in &parsed {
             assert!(schemas.contains(parsed_schema));
         }
     }
+    Ok(())
 }
 
 #[test]
 /// Test that a type that is depended on by more than one other type is parsed correctly when all
 /// definitions are passed in as a list. This should work regardless of the ordering of the list.
-fn test_parse_list_shared_dependency() {
+fn test_parse_list_shared_dependency() -> TestResult {
     init();
     let schema_a_str = r#"{
         "name": "A",
@@ -1019,21 +1034,22 @@ fn test_parse_list_shared_dependency() {
     }"#;
 
     let parsed =
-        Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str]).expect("Test failed");
+        Schema::parse_list(&[schema_a_str, schema_b_str, schema_c_str])?;
     let schema_strs = vec![schema_a_str, schema_b_str, schema_c_str];
     for schema_str_perm in permutations(&schema_strs) {
         let schema_str_perm: Vec<&str> = schema_str_perm.iter().map(|s| **s).collect();
-        let schemas = Schema::parse_list(&schema_str_perm).expect("Test failed");
+        let schemas = Schema::parse_list(&schema_str_perm)?;
         assert_eq!(schemas.len(), 3);
         for parsed_schema in &parsed {
             assert!(schemas.contains(parsed_schema));
         }
     }
+    Ok(())
 }
 
 #[test]
 /// Test that trying to parse two schemas with the same fullname returns an Error
-fn test_name_collision_error() {
+fn test_name_collision_error() -> TestResult {
     init();
     let schema_str_1 = r#"{
         "name": "foo.A",
@@ -1052,11 +1068,12 @@ fn test_name_collision_error() {
     }"#;
 
     let _ = Schema::parse_list(&[schema_str_1, schema_str_2]).expect_err("Test failed");
+    Ok(())
 }
 
 #[test]
 /// Test that having the same name but different fullnames does not return an error
-fn test_namespace_prevents_collisions() {
+fn test_namespace_prevents_collisions() -> TestResult {
     init();
     let schema_str_1 = r#"{
         "name": "A",
@@ -1074,10 +1091,11 @@ fn test_namespace_prevents_collisions() {
         ]
     }"#;
 
-    let parsed = Schema::parse_list(&[schema_str_1, schema_str_2]).expect("Test failed");
-    let parsed_1 = Schema::parse_str(schema_str_1).expect("Test failed");
-    let parsed_2 = Schema::parse_str(schema_str_2).expect("Test failed");
+    let parsed = Schema::parse_list(&[schema_str_1, schema_str_2])?;
+    let parsed_1 = Schema::parse_str(schema_str_1)?;
+    let parsed_2 = Schema::parse_str(schema_str_2)?;
     assert_eq!(parsed, vec!(parsed_1, parsed_2));
+    Ok(())
 }
 
 // The fullname is determined in one of the following ways:
@@ -1106,96 +1124,105 @@ fn test_namespace_prevents_collisions() {
 // equivalent.
 
 #[test]
-fn test_fullname_name_and_namespace_specified() {
+fn test_fullname_name_and_namespace_specified() -> TestResult {
     init();
     let name: Name =
-        serde_json::from_str(r#"{"name": "a", "namespace": "o.a.h", "aliases": null}"#).unwrap();
+        serde_json::from_str(r#"{"name": "a", "namespace": "o.a.h", "aliases": null}"#)?;
     let fullname = name.fullname(None);
     assert_eq!("o.a.h.a", fullname);
+    Ok(())
 }
 
 #[test]
-fn test_fullname_fullname_and_namespace_specified() {
+fn test_fullname_fullname_and_namespace_specified() -> TestResult {
     init();
-    let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": "o.a.h"}"#).unwrap();
+    let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": "o.a.h"}"#)?;
     assert_eq!(&name.name, "d");
     assert_eq!(name.namespace, Some("a.b.c".to_owned()));
     let fullname = name.fullname(None);
     assert_eq!("a.b.c.d", fullname);
+    Ok(())
 }
 
 #[test]
-fn test_fullname_name_and_default_namespace_specified() {
+fn test_fullname_name_and_default_namespace_specified() -> TestResult {
     init();
-    let name: Name = serde_json::from_str(r#"{"name": "a", "namespace": null}"#).unwrap();
+    let name: Name = serde_json::from_str(r#"{"name": "a", "namespace": null}"#)?;
     assert_eq!(&name.name, "a");
     assert_eq!(name.namespace, None);
     let fullname = name.fullname(Some("b.c.d".into()));
     assert_eq!("b.c.d.a", fullname);
+    Ok(())
 }
 
 #[test]
-fn test_fullname_fullname_and_default_namespace_specified() {
+fn test_fullname_fullname_and_default_namespace_specified() -> TestResult {
     init();
-    let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": null}"#).unwrap();
+    let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": null}"#)?;
     assert_eq!(&name.name, "d");
     assert_eq!(name.namespace, Some("a.b.c".to_owned()));
     let fullname = name.fullname(Some("o.a.h".into()));
     assert_eq!("a.b.c.d", fullname);
+    Ok(())
 }
 
 #[test]
-fn test_avro_3452_parsing_name_without_namespace() {
+fn test_avro_3452_parsing_name_without_namespace() -> TestResult {
     init();
-    let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d"}"#).unwrap();
+    let name: Name = serde_json::from_str(r#"{"name": "a.b.c.d"}"#)?;
     assert_eq!(&name.name, "d");
     assert_eq!(name.namespace, Some("a.b.c".to_owned()));
     let fullname = name.fullname(None);
     assert_eq!("a.b.c.d", fullname);
+    Ok(())
 }
 
 #[test]
-fn test_avro_3452_parsing_name_with_leading_dot_without_namespace() {
+fn test_avro_3452_parsing_name_with_leading_dot_without_namespace() -> TestResult {
     init();
-    let name: Name = serde_json::from_str(r#"{"name": ".a"}"#).unwrap();
+    let name: Name = serde_json::from_str(r#"{"name": ".a"}"#)?;
     assert_eq!(&name.name, "a");
     assert_eq!(name.namespace, None);
     assert_eq!("a", name.fullname(None));
+    Ok(())
 }
 
 #[test]
-fn test_avro_3452_parse_json_without_name_field() {
+fn test_avro_3452_parse_json_without_name_field() -> TestResult {
     init();
     let result: serde_json::error::Result<Name> = serde_json::from_str(r#"{"unknown": "a"}"#);
     assert!(&result.is_err());
     assert_eq!(result.unwrap_err().to_string(), "No `name` field");
+    Ok(())
 }
 
 #[test]
-fn test_fullname_fullname_namespace_and_default_namespace_specified() {
+fn test_fullname_fullname_namespace_and_default_namespace_specified() -> TestResult {
     init();
     let name: Name =
         serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": "o.a.a", "aliases": null}"#)
-            .unwrap();
+            ?;
     assert_eq!(&name.name, "d");
     assert_eq!(name.namespace, Some("a.b.c".to_owned()));
     let fullname = name.fullname(Some("o.a.h".into()));
     assert_eq!("a.b.c.d", fullname);
+    Ok(())
 }
 
 #[test]
-fn test_fullname_name_namespace_and_default_namespace_specified() {
+fn test_fullname_name_namespace_and_default_namespace_specified() -> TestResult {
     init();
     let name: Name =
-        serde_json::from_str(r#"{"name": "a", "namespace": "o.a.a", "aliases": null}"#).unwrap();
+        serde_json::from_str(r#"{"name": "a", "namespace": "o.a.a", "aliases": null}"#)?;
     assert_eq!(&name.name, "a");
     assert_eq!(name.namespace, Some("o.a.a".to_owned()));
     let fullname = name.fullname(Some("o.a.h".into()));
     assert_eq!("o.a.a.a", fullname);
+    Ok(())
 }
 
 #[test]
-fn test_doc_attributes() {
+fn test_doc_attributes() -> TestResult {
     init();
     fn assert_doc(schema: &Schema) {
         match schema {
@@ -1208,7 +1235,7 @@ fn test_doc_attributes() {
     }
 
     for (raw_schema, _) in DOC_EXAMPLES.iter() {
-        let original_schema = Schema::parse_str(raw_schema).unwrap();
+        let original_schema = Schema::parse_str(raw_schema)?;
         assert_doc(&original_schema);
         if let Schema::Record(RecordSchema { fields, .. }) = original_schema {
             for f in fields {
@@ -1216,6 +1243,7 @@ fn test_doc_attributes() {
             }
         }
     }
+    Ok(())
 }
 
 /*
@@ -1233,17 +1261,17 @@ fn test_other_attributes() {
     }
 
     for (raw_schema, _) in OTHER_ATTRIBUTES_EXAMPLES.iter() {
-        let schema = Schema::parse_str(raw_schema).unwrap();
+        let schema = Schema::parse_str(raw_schema)?;
         // all inputs have at least some user-defined attributes
         assert!(schema.other_attributes.is_some());
-        for prop in schema.other_attributes.unwrap().iter() {
+        for prop in schema.other_attributes?.iter() {
             assert_attribute_type(prop);
         }
         if let Schema::Record { fields, .. } = schema {
            for f in fields {
                // all fields in the record have at least some user-defined attributes
                assert!(f.schema.other_attributes.is_some());
-               for prop in f.schema.other_attributes.unwrap().iter() {
+               for prop in f.schema.other_attributes?.iter() {
                    assert_attribute_type(prop);
                }
            }
@@ -1272,7 +1300,7 @@ fn test_root_error_is_not_swallowed_on_parse_error() -> Result<(), String> {
 
 // AVRO-3302
 #[test]
-fn test_record_schema_with_cyclic_references() {
+fn test_record_schema_with_cyclic_references() -> TestResult {
     init();
     let schema = Schema::parse_str(
         r#"
@@ -1293,7 +1321,7 @@ fn test_record_schema_with_cyclic_references() {
             }
         "#,
     )
-    .unwrap();
+    ?;
 
     let mut datum = Record::new(&schema).unwrap();
     datum.put(
@@ -1326,16 +1354,17 @@ fn test_record_schema_with_cyclic_references() {
     if let Err(err) = writer.append(datum) {
         panic!("An error occurred while writing datum: {err:?}")
     }
-    let bytes = writer.into_inner().unwrap();
+    let bytes = writer.into_inner()?;
     assert_eq!(316, bytes.len());
 
     match Reader::new(&mut bytes.as_slice()) {
         Ok(mut reader) => match reader.next() {
-            Some(value) => log::debug!("{:?}", value.unwrap()),
+            Some(value) => log::debug!("{:?}", value?),
             None => panic!("No value was read!"),
         },
         Err(err) => panic!("An error occurred while reading datum: {err:?}"),
     }
+    Ok(())
 }
 
 /*
@@ -1343,12 +1372,12 @@ fn test_record_schema_with_cyclic_references() {
 #[test]
 fn test_decimal_valid_type_attributes() {
     init();
-    let fixed_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[0]).unwrap();
+    let fixed_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[0])?;
     assert_eq!(4, fixed_decimal.get_attribute("precision"));
     assert_eq!(2, fixed_decimal.get_attribute("scale"));
     assert_eq!(2, fixed_decimal.get_attribute("size"));
 
-    let bytes_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[1]).unwrap();
+    let bytes_decimal = Schema::parse_str(DECIMAL_LOGICAL_TYPE_ATTRIBUTES[1])?;
     assert_eq!(4, bytes_decimal.get_attribute("precision"));
     assert_eq!(0, bytes_decimal.get_attribute("scale"));
 }
@@ -1356,7 +1385,7 @@ fn test_decimal_valid_type_attributes() {
 
 // https://github.com/flavray/avro-rs/issues/47
 #[test]
-fn avro_old_issue_47() {
+fn avro_old_issue_47() -> TestResult {
     init();
     let schema_str = r#"
     {
@@ -1367,7 +1396,7 @@ fn avro_old_issue_47() {
         {"name": "b", "type": "string"}
       ]
     }"#;
-    let schema = Schema::parse_str(schema_str).unwrap();
+    let schema = Schema::parse_str(schema_str)?;
 
     use serde::{Deserialize, Serialize};
 
@@ -1382,5 +1411,6 @@ fn avro_old_issue_47() {
         a: 1,
     };
 
-    let _ = to_avro_datum(&schema, to_value(record).unwrap()).unwrap();
+    let _ = to_avro_datum(&schema, to_value(record)?)?;
+    Ok(())
 }
diff --git a/lang/rust/avro/tests/shared.rs b/lang/rust/avro/tests/shared.rs
index f5686129c..ab85604e5 100644
--- a/lang/rust/avro/tests/shared.rs
+++ b/lang/rust/avro/tests/shared.rs
@@ -23,11 +23,12 @@ use std::{
     path::Path,
     slice::Iter,
 };
+use apache_avro_test_helper::TestResult;
 
 const ROOT_DIRECTORY: &str = "../../../share/test/data/schemas";
 
 #[test]
-fn test_schema() {
+fn test_schema() -> TestResult {
     let directory: ReadDir = scan_shared_folder();
     let mut result: Result<(), ErrorsDesc> = Ok(());
     for f in directory {
@@ -54,6 +55,7 @@ fn test_schema() {
     if let Err(e) = result {
         core::panic!("{}", e)
     }
+    Ok(())
 }
 
 #[derive(Debug)]
diff --git a/lang/rust/avro/tests/to_from_avro_datum_schemata.rs b/lang/rust/avro/tests/to_from_avro_datum_schemata.rs
index d05025ab7..e27f1e625 100644
--- a/lang/rust/avro/tests/to_from_avro_datum_schemata.rs
+++ b/lang/rust/avro/tests/to_from_avro_datum_schemata.rs
@@ -18,7 +18,7 @@
 use apache_avro::{
     from_avro_datum_schemata, to_avro_datum_schemata, types::Value, Codec, Reader, Schema, Writer,
 };
-use apache_avro_test_helper::init;
+use apache_avro_test_helper::{init, TestResult};
 
 static SCHEMA_A_STR: &str = r#"{
         "name": "A",
@@ -37,7 +37,7 @@ static SCHEMA_B_STR: &str = r#"{
     }"#;
 
 #[test]
-fn test_avro_3683_multiple_schemata_to_from_avro_datum() {
+fn test_avro_3683_multiple_schemata_to_from_avro_datum() -> TestResult {
     init();
 
     let record: Value = Value::Record(vec![(
@@ -45,21 +45,23 @@ fn test_avro_3683_multiple_schemata_to_from_avro_datum() {
         Value::Record(vec![(String::from("field_a"), Value::Float(1.0))]),
     )]);
 
-    let schemata: Vec<Schema> = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR]).unwrap();
+    let schemata: Vec<Schema> = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR])?;
     let schemata: Vec<&Schema> = schemata.iter().collect();
 
     // this is the Schema we want to use for write/read
     let schema_b = schemata[1];
     let expected: Vec<u8> = vec![0, 0, 128, 63];
-    let actual = to_avro_datum_schemata(schema_b, schemata.clone(), record.clone()).unwrap();
+    let actual = to_avro_datum_schemata(schema_b, schemata.clone(), record.clone())?;
     assert_eq!(actual, expected);
 
-    let value = from_avro_datum_schemata(schema_b, schemata, &mut actual.as_slice(), None).unwrap();
+    let value = from_avro_datum_schemata(schema_b, schemata, &mut actual.as_slice(), None)?;
     assert_eq!(value, record);
+
+    Ok(())
 }
 
 #[test]
-fn test_avro_3683_multiple_schemata_writer_reader() {
+fn test_avro_3683_multiple_schemata_writer_reader() -> TestResult {
     init();
 
     let record: Value = Value::Record(vec![(
@@ -67,7 +69,7 @@ fn test_avro_3683_multiple_schemata_writer_reader() {
         Value::Record(vec![(String::from("field_a"), Value::Float(1.0))]),
     )]);
 
-    let schemata: Vec<Schema> = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR]).unwrap();
+    let schemata: Vec<Schema> = Schema::parse_list(&[SCHEMA_A_STR, SCHEMA_B_STR])?;
     let schemata: Vec<&Schema> = schemata.iter().collect();
 
     // this is the Schema we want to use for write/read
@@ -75,10 +77,12 @@ fn test_avro_3683_multiple_schemata_writer_reader() {
     let mut output: Vec<u8> = Vec::new();
 
     let mut writer = Writer::with_schemata(schema_b, schemata.clone(), &mut output, Codec::Null);
-    writer.append(record.clone()).unwrap();
-    writer.flush().unwrap();
+    writer.append(record.clone())?;
+    writer.flush()?;
 
-    let reader = Reader::with_schemata(schema_b, schemata, output.as_slice()).unwrap();
+    let reader = Reader::with_schemata(schema_b, schemata, output.as_slice())?;
     let value = reader.into_iter().next().unwrap().unwrap();
     assert_eq!(value, record);
+
+    Ok(())
 }
diff --git a/lang/rust/avro_test_helper/Cargo.toml b/lang/rust/avro_test_helper/Cargo.toml
index 811cc579d..402b26195 100644
--- a/lang/rust/avro_test_helper/Cargo.toml
+++ b/lang/rust/avro_test_helper/Cargo.toml
@@ -31,6 +31,7 @@ documentation = "https://docs.rs/apache-avro-test-helper"
 
 
 [dependencies]
+anyhow = { default-features = false, version = "1.0.71", features = ["std"] }
 color-backtrace = { default-features = false, version = "0.5.1" }
 ctor = { default-features = false, version = "0.2.0" }
 env_logger = { default-features = false, version = "0.10.0" }
diff --git a/lang/rust/avro_test_helper/src/lib.rs b/lang/rust/avro_test_helper/src/lib.rs
index 235b4c518..545bccc89 100644
--- a/lang/rust/avro_test_helper/src/lib.rs
+++ b/lang/rust/avro_test_helper/src/lib.rs
@@ -45,6 +45,22 @@ fn after_all() {
     logger::clear_log_messages();
 }
 
+/// A custom error type for tests.
+#[derive(Debug)]
+pub enum TestError {}
+
+/// A converter of any error into [TestError].
+/// It is used to print better error messages in the tests.
+/// Borrowed from https://bluxte.net/musings/2023/01/08/improving_failure_messages_rust_tests/
+impl<Err: std::fmt::Display> From<Err> for TestError {
+    #[track_caller]
+    fn from(err: Err) -> Self {
+        panic!("{}: {}", std::any::type_name::<Err>(), err);
+    }
+}
+
+pub type TestResult = anyhow::Result<(), TestError>;
+
 /// Does nothing. Just loads the crate.
 /// Should be used in the integration tests, because they do not use [dev-dependencies]
 /// and do not auto-load this crate.