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 13:29:56 UTC

[avro] branch better-error-messages-in-tests updated (a269b4da6 -> db391b8f7)

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

mgrigorov pushed a change to branch better-error-messages-in-tests
in repository https://gitbox.apache.org/repos/asf/avro.git


 discard a269b4da6 Print friendlier error messages in the tests
     add 91f5fa753 Bump log from 0.4.17 to 0.4.18 in /lang/rust (#2261)
     add d1b5f9ad9 Bump syn from 2.0.16 to 2.0.18 in /lang/rust (#2260)
     add cdfd66fed AVRO-3764: [Rust]: Add resolve method with schemata for an automatic Schema::Ref resolving (#2262)
     new db391b8f7 AVRO-3766: [Rust] Print fliendlier errors when test cases fail

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (a269b4da6)
            \
             N -- N -- N   refs/heads/better-error-messages-in-tests (db391b8f7)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 lang/rust/Cargo.lock                               |  27 ++--
 lang/rust/avro/Cargo.toml                          |   2 +-
 lang/rust/avro/src/schema.rs                       |   2 +-
 lang/rust/avro/src/types.rs                        |  53 +++++++
 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_derive/Cargo.toml                   |   2 +-
 lang/rust/avro_test_helper/Cargo.toml              |   2 +-
 9 files changed, 183 insertions(+), 97 deletions(-)


[avro] 01/01: AVRO-3766: [Rust] Print fliendlier errors when test cases fail

Posted by mg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch better-error-messages-in-tests
in repository https://gitbox.apache.org/repos/asf/avro.git

commit db391b8f7dff9cba4ae8b31e23dca2f0b3ec0d1d
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Mon May 29 21:09:07 2023 +0300

    AVRO-3766: [Rust] Print fliendlier errors when test cases fail
    
    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.