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

Kriskras99 pushed a commit to branch feat/derived_schema_test
in repository https://gitbox.apache.org/repos/asf/avro-rs.git

commit bb9dcde939cbf59585d59de1e8e9b12ee3474924
Author: Kriskras99 <[email protected]>
AuthorDate: Tue Jun 30 09:33:55 2026 +0200

    feat: Derive tests for derived schemas
---
 avro/src/serde/derive.rs                          |  5 ++
 avro/tests/avro-rs-226.rs                         |  4 ++
 avro/tests/get_record_fields.rs                   |  2 +
 avro/tests/serde_human_readable_false.rs          |  3 +
 avro/tests/serde_human_readable_true.rs           |  3 +
 avro_derive/src/attributes/avro.rs                |  3 +
 avro_derive/src/attributes/mod.rs                 |  2 +
 avro_derive/src/enums/bare_union.rs               |  1 +
 avro_derive/src/enums/plain.rs                    |  1 +
 avro_derive/src/enums/record_internally_tagged.rs |  1 +
 avro_derive/src/enums/record_tag_content.rs       |  1 +
 avro_derive/src/enums/union_of_records.rs         |  1 +
 avro_derive/src/implementation.rs                 | 87 ++++++++++++++++++++++-
 avro_derive/src/structs.rs                        |  5 +-
 avro_derive/tests/derive.rs                       | 52 ++++++++++++--
 avro_derive/tests/enum.rs                         | 42 +++++------
 avro_derive/tests/serde.rs                        | 21 ++++++
 17 files changed, 207 insertions(+), 27 deletions(-)

diff --git a/avro/src/serde/derive.rs b/avro/src/serde/derive.rs
index 6d66fce..f588abc 100644
--- a/avro/src/serde/derive.rs
+++ b/avro/src/serde/derive.rs
@@ -102,6 +102,11 @@ use crate::{
 ///
 ///    Use the schema of the inner field directly. Is only allowed on structs 
with only one unskipped field.
 ///
+///  - `#[avro(test = false)]`
+///
+///    To disable generating tests for derived schemas. This is useful if you 
use a different [validator](crate::validator)
+///    or the `unnameable_test_items` lint is triggered because the type your 
deriving is inside a function.
+///
 ///
 /// #### Variant attributes
 ///
diff --git a/avro/tests/avro-rs-226.rs b/avro/tests/avro-rs-226.rs
index b98b9d2..ee0aea3 100644
--- a/avro/tests/avro-rs-226.rs
+++ b/avro/tests/avro-rs-226.rs
@@ -46,6 +46,7 @@ where
 #[test]
 fn 
avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_middle_field() 
-> TestResult {
     #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)]
+    #[avro(tests = false)]
     struct T {
         x: Option<i8>,
         #[serde(skip_serializing_if = "Option::is_none")]
@@ -67,6 +68,7 @@ fn 
avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_middle_field
 #[test]
 fn 
avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_first_field() 
-> TestResult {
     #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)]
+    #[avro(tests = false)]
     struct T {
         #[serde(skip_serializing_if = "Option::is_none")]
         #[avro(default = "null")]
@@ -88,6 +90,7 @@ fn 
avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_first_field(
 #[test]
 fn 
avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_last_field() 
-> TestResult {
     #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)]
+    #[avro(tests = false)]
     struct T {
         x: Option<i8>,
         y: Option<String>,
@@ -109,6 +112,7 @@ fn 
avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_last_field()
 #[test]
 fn avro_rs_226_index_out_of_bounds_with_serde_skip_multiple_fields() -> 
TestResult {
     #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)]
+    #[avro(tests = false)]
     struct T {
         no_skip1: Option<i8>,
         #[serde(skip_serializing)]
diff --git a/avro/tests/get_record_fields.rs b/avro/tests/get_record_fields.rs
index 5bab721..8e6519f 100644
--- a/avro/tests/get_record_fields.rs
+++ b/avro/tests/get_record_fields.rs
@@ -26,6 +26,7 @@ use apache_avro_test_helper::TestResult;
 #[test]
 fn avro_rs_448_default_get_record_fields_no_recursion() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         _a: i32,
         _b: String,
@@ -67,6 +68,7 @@ fn avro_rs_448_default_get_record_fields_no_recursion() -> 
TestResult {
 #[test]
 fn avro_rs_448_default_get_record_fields_recursion() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         _a: i32,
         _b: Option<Box<Foo>>,
diff --git a/avro/tests/serde_human_readable_false.rs 
b/avro/tests/serde_human_readable_false.rs
index e4e6013..f9656c7 100644
--- a/avro/tests/serde_human_readable_false.rs
+++ b/avro/tests/serde_human_readable_false.rs
@@ -65,6 +65,7 @@ fn avro_rs_53_uuid_with_fixed() -> TestResult {
 #[test]
 fn avro_rs_440_uuid_string() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     struct CustomUuid {
         #[avro(with = || Schema::Uuid(UuidSchema::String))]
@@ -88,6 +89,7 @@ fn avro_rs_440_uuid_string() -> TestResult {
 #[test]
 fn avro_rs_440_uuid_bytes() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     struct CustomUuid {
         #[avro(with = || Schema::Uuid(UuidSchema::Bytes))]
@@ -116,6 +118,7 @@ fn avro_rs_440_uuid_bytes() -> TestResult {
 #[test]
 fn avro_rs_440_uuid_fixed() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     struct CustomUuid {
         inner: Uuid,
diff --git a/avro/tests/serde_human_readable_true.rs 
b/avro/tests/serde_human_readable_true.rs
index f23570c..2873edb 100644
--- a/avro/tests/serde_human_readable_true.rs
+++ b/avro/tests/serde_human_readable_true.rs
@@ -64,6 +64,7 @@ fn avro_rs_53_uuid_with_string_true() -> TestResult {
 #[test]
 fn avro_rs_440_uuid_string() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     struct CustomUuid {
         #[avro(with = || Schema::Uuid(UuidSchema::String))]
@@ -89,6 +90,7 @@ fn avro_rs_440_uuid_string() -> TestResult {
 #[test]
 fn avro_rs_440_uuid_bytes() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     struct CustomUuid {
         #[avro(with = || Schema::Uuid(UuidSchema::Bytes))]
@@ -112,6 +114,7 @@ fn avro_rs_440_uuid_bytes() -> TestResult {
 #[test]
 fn avro_rs_440_uuid_fixed() -> TestResult {
     #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     struct CustomUuid {
         inner: Uuid,
diff --git a/avro_derive/src/attributes/avro.rs 
b/avro_derive/src/attributes/avro.rs
index bc8b5ef..e790f84 100644
--- a/avro_derive/src/attributes/avro.rs
+++ b/avro_derive/src/attributes/avro.rs
@@ -85,6 +85,9 @@ pub struct ContainerAttributes {
     /// Force the generator to use a certain schema representation
     #[darling(default)]
     pub repr: Option<Repr>,
+    /// Force the generator to use a certain schema representation
+    #[darling(default = || true)]
+    pub tests: bool,
 }
 
 impl ContainerAttributes {
diff --git a/avro_derive/src/attributes/mod.rs 
b/avro_derive/src/attributes/mod.rs
index 19e8a89..e316db4 100644
--- a/avro_derive/src/attributes/mod.rs
+++ b/avro_derive/src/attributes/mod.rs
@@ -135,6 +135,7 @@ pub struct NamedTypeOptions {
     pub transparent: bool,
     pub default: Option<Value>,
     pub repr: Option<Repr>,
+    pub tests: bool,
 }
 
 impl NamedTypeOptions {
@@ -261,6 +262,7 @@ impl NamedTypeOptions {
             transparent: serde.transparent,
             default,
             repr,
+            tests: avro.tests,
         })
     }
 }
diff --git a/avro_derive/src/enums/bare_union.rs 
b/avro_derive/src/enums/bare_union.rs
index 3fdf117..4babd3b 100644
--- a/avro_derive/src/enums/bare_union.rs
+++ b/avro_derive/src/enums/bare_union.rs
@@ -109,5 +109,6 @@ pub fn to_implementation(
             .default
             .map(json_value_expr)
             .map(|t| quote! { ::std::option::Option::Some(#t)}),
+        container_attrs.tests,
     ))
 }
diff --git a/avro_derive/src/enums/plain.rs b/avro_derive/src/enums/plain.rs
index 7d9562b..da6e18f 100644
--- a/avro_derive/src/enums/plain.rs
+++ b/avro_derive/src/enums/plain.rs
@@ -137,6 +137,7 @@ pub fn to_implementation(
             .default
             .map(json_value_expr)
             .map(|t| quote! { ::std::option::Option::Some(#t)}),
+        container_attrs.tests,
     ))
 }
 
diff --git a/avro_derive/src/enums/record_internally_tagged.rs 
b/avro_derive/src/enums/record_internally_tagged.rs
index ec8208a..4eefc0f 100644
--- a/avro_derive/src/enums/record_internally_tagged.rs
+++ b/avro_derive/src/enums/record_internally_tagged.rs
@@ -212,5 +212,6 @@ pub fn to_implementation(
             .default
             .map(json_value_expr)
             .map(|t| quote! { ::std::option::Option::Some(#t)}),
+        container_attrs.tests,
     ))
 }
diff --git a/avro_derive/src/enums/record_tag_content.rs 
b/avro_derive/src/enums/record_tag_content.rs
index ab922e9..f1170cf 100644
--- a/avro_derive/src/enums/record_tag_content.rs
+++ b/avro_derive/src/enums/record_tag_content.rs
@@ -168,5 +168,6 @@ pub fn to_implementation(
             .default
             .map(json_value_expr)
             .map(|t| quote! { ::std::option::Option::Some(#t)}),
+        container_attrs.tests,
     ))
 }
diff --git a/avro_derive/src/enums/union_of_records.rs 
b/avro_derive/src/enums/union_of_records.rs
index 49db73b..9c68590 100644
--- a/avro_derive/src/enums/union_of_records.rs
+++ b/avro_derive/src/enums/union_of_records.rs
@@ -94,5 +94,6 @@ pub fn to_implementation(
             .default
             .map(json_value_expr)
             .map(|t| quote! { ::std::option::Option::Some(#t)}),
+        container_attrs.tests,
     ))
 }
diff --git a/avro_derive/src/implementation.rs 
b/avro_derive/src/implementation.rs
index 54f5a8b..4ec84d0 100644
--- a/avro_derive/src/implementation.rs
+++ b/avro_derive/src/implementation.rs
@@ -17,7 +17,7 @@
 
 use crate::utils::name_expr;
 use proc_macro2::{Ident, TokenStream};
-use quote::quote;
+use quote::{format_ident, quote};
 use syn::Generics;
 
 pub struct Implementation {
@@ -35,6 +35,8 @@ pub struct Implementation {
     record_fields_expr: TokenStream,
     /// An expression that resolves to a `Option<serde_json::Value>`
     field_default_expr: TokenStream,
+    /// Tests that will be run if the type has no generics and they haven't 
been disabled via an attribute.
+    tests: Option<Vec<Test>>,
 }
 
 impl Implementation {
@@ -49,6 +51,7 @@ impl Implementation {
         schema_expr: TokenStream,
         record_fields_expr: Option<TokenStream>,
         field_default_expr: Option<TokenStream>,
+        tests: bool,
     ) -> Implementation {
         let name_expr = name_expr(name);
         let schema_expr = quote! {
@@ -68,6 +71,7 @@ impl Implementation {
             schema_expr,
             record_fields_expr,
             field_default_expr,
+            tests,
         )
     }
 
@@ -77,8 +81,9 @@ impl Implementation {
         schema_expr: TokenStream,
         record_fields_expr: Option<TokenStream>,
         field_default_expr: Option<TokenStream>,
+        tests: bool,
     ) -> Implementation {
-        Self {
+        let mut this = Self {
             ident,
             generics,
             schema_expr,
@@ -86,6 +91,36 @@ impl Implementation {
                 .unwrap_or_else(|| quote! { ::std::option::Option::None }),
             field_default_expr: field_default_expr
                 .unwrap_or_else(|| quote! { ::std::option::Option::None }),
+            tests: tests.then(Vec::new),
+        };
+
+        this.add_schema_test();
+
+        this
+    }
+
+    pub fn add_test(&mut self, test: Test) {
+        if let Some(tests) = &mut self.tests {
+            tests.push(test);
+        }
+    }
+
+    fn add_schema_test(&mut self) {
+        // Only add the schema test if there are no generics to deal with. I 
think it should be possible
+        // to be able to generate the test if there are only lifetimes, but 
that needs more experimentation.
+        if self.generics.lifetimes().count() == 0
+            && self.generics.type_params().count() == 0
+            && self.generics.const_params().count() == 0
+        {
+            let ident = &self.ident;
+            self.add_test(Test {
+                name: "schema".to_string(),
+                body: quote! {
+                    eprintln!("Invalid schema, if this is because a different 
validator is used at runtime you can disable generating tests with 
`#[avro(tests = false)]`");
+                    <#ident as ::apache_avro::serde::AvroSchema>::get_schema();
+                },
+                should_panic: None,
+            });
         }
     }
 
@@ -96,6 +131,24 @@ impl Implementation {
         let record_fields_expr = self.record_fields_expr;
         let field_default_expr = self.field_default_expr;
 
+        let tests = if let Some(tests) = self.tests {
+            let test_module_name = format!(
+                "_apache_avro_derive_tests_for_{}",
+                ident.to_string().to_lowercase()
+            );
+            let tests = tests
+                .into_iter()
+                .map(|t| t.into_token_stream(&test_module_name));
+            quote! {
+                #(
+                    #[cfg(test)]
+                    #tests
+                )*
+            }
+        } else {
+            TokenStream::new()
+        };
+
         quote! {
             #[automatically_derived]
             impl #impl_generics ::apache_avro::AvroSchemaComponent for #ident 
#ty_generics #where_clause {
@@ -111,6 +164,36 @@ impl Implementation {
                     #field_default_expr
                 }
             }
+
+            #tests
+        }
+    }
+}
+
+pub struct Test {
+    /// The name of the test.
+    pub name: String,
+    /// The body of the test function, so without `fn some_name() {`.
+    pub body: TokenStream,
+    /// If this test should panic, this should be the message.
+    pub should_panic: Option<String>,
+}
+
+impl Test {
+    pub fn into_token_stream(self, prefix: &str) -> TokenStream {
+        let name = format_ident!("{prefix}_{}", &self.name);
+        let body = &self.body;
+        let should_panic = if let Some(expected) = &self.should_panic {
+            quote! { #[should_panic(expected = #expected)] }
+        } else {
+            TokenStream::new()
+        };
+        quote! {
+            #[test]
+            #should_panic
+            fn #name() {
+                #body
+            }
         }
     }
 }
diff --git a/avro_derive/src/structs.rs b/avro_derive/src/structs.rs
index 9e242b5..891c43f 100644
--- a/avro_derive/src/structs.rs
+++ b/avro_derive/src/structs.rs
@@ -35,7 +35,7 @@ pub fn to_implementation(
     data: DataStruct,
 ) -> Result<Implementation, Vec<syn::Error>> {
     if container_attrs.transparent {
-        transparent(input_span, ident, generics, data)
+        transparent(input_span, ident, generics, &container_attrs, data)
     } else {
         normal(ident, generics, container_attrs, data)
     }
@@ -85,6 +85,7 @@ fn normal(
             .default
             .map(json_value_expr)
             .map(|t| quote! { ::std::option::Option::Some(#t)}),
+        container_attrs.tests,
     ))
 }
 
@@ -92,6 +93,7 @@ fn transparent(
     input_span: Span,
     ident: Ident,
     generics: Generics,
+    container_attrs: &NamedTypeOptions,
     data: DataStruct,
 ) -> Result<Implementation, Vec<syn::Error>> {
     match data.fields {
@@ -119,6 +121,7 @@ fn transparent(
                     field_to_schema_expr(&field, &attrs.with)?,
                     Some(field_to_record_fields_expr(&field, &attrs.with)?),
                     Some(field_default_expr),
+                    container_attrs.tests,
                 ))
             } else {
                 Err(vec![syn::Error::new(
diff --git a/avro_derive/tests/derive.rs b/avro_derive/tests/derive.rs
index c4c7d21..df48539 100644
--- a/avro_derive/tests/derive.rs
+++ b/avro_derive/tests/derive.rs
@@ -209,7 +209,7 @@ fn test_complex_namespace() {
 #[test]
 fn avro_rs_239_test_named_record() {
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq, Eq)]
-    #[avro(namespace = "com.testing.namespace")]
+    #[avro(namespace = "com.testing.namespace", tests = false)]
     #[serde(rename = "Other")]
     struct TestNamedRecord {
         a: i32,
@@ -658,6 +658,7 @@ fn test_enum() {
 fn avro_rs_239_test_enum_named() {
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq, Eq)]
     #[serde(rename = "Other", rename_all = "snake_case")]
+    #[avro(tests = false)]
     enum TestNamedEnum {
         A,
         B,
@@ -667,6 +668,7 @@ fn avro_rs_239_test_enum_named() {
     }
 
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq, Eq)]
+    #[avro(tests = false)]
     struct TestNamedEnumNested {
         a: TestNamedEnum,
         b: String,
@@ -1361,6 +1363,7 @@ fn test_basic_enum_with_aliases2() {
 #[test]
 fn test_basic_struct_with_defaults() {
     #[derive(Debug, Deserialize, Serialize, AvroSchema, Clone, PartialEq, Eq)]
+    #[avro(tests = false)]
     enum MyEnum {
         Foo,
         Bar,
@@ -1368,6 +1371,7 @@ fn test_basic_struct_with_defaults() {
     }
 
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct TestBasicStructWithDefaultValues {
         #[avro(default = "123")]
         a: i32,
@@ -1502,15 +1506,13 @@ fn test_basic_struct_with_defaults() {
 
 #[test]
 fn avro_3633_test_basic_struct_with_skip_attribute() {
-    // Note: If using the skip attribute together with serialization,
-    // the serde's skip attribute needs also to be added
-
     #[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
     struct TestBasicStructNoSchema {
         field: bool,
     }
 
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct TestBasicStructWithSkipAttribute {
         #[serde(skip)]
         condition: bool,
@@ -1583,6 +1585,7 @@ fn avro_3633_test_basic_struct_with_skip_attribute() {
 #[test]
 fn avro_3633_test_basic_struct_with_rename_attribute() {
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct TestBasicStructWithRenameAttribute {
         #[serde(rename = "a1")]
         a: bool,
@@ -1640,6 +1643,7 @@ fn avro_3633_test_basic_struct_with_rename_attribute() {
 #[test]
 fn test_avro_3663_raw_identifier_field_name() {
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct TestRawIdent {
         r#type: bool,
     }
@@ -1657,6 +1661,7 @@ fn test_avro_3663_raw_identifier_field_name() {
 fn avro_3962_fields_documentation() {
     /// Foo docs
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[allow(dead_code)]
     struct Foo {
         /// a's Rustdoc
@@ -1680,11 +1685,13 @@ fn avro_3962_fields_documentation() {
 #[test]
 fn avro_rs_247_serde_flatten_support() {
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct Nested {
         a: bool,
     }
 
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct Foo {
         #[serde(flatten)]
         nested: Nested,
@@ -1723,17 +1730,20 @@ fn avro_rs_247_serde_nested_flatten_support() {
     use serde::{Deserialize, Serialize};
 
     #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)]
+    #[avro(tests = false)]
     pub struct NestedFoo {
         one: u32,
     }
 
     #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)]
+    #[avro(tests = false)]
     pub struct Foo {
         #[serde(flatten)]
         nested_foo: NestedFoo,
     }
 
     #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)]
+    #[avro(tests = false)]
     struct Bar {
         foo: Foo,
         two: u32,
@@ -1780,11 +1790,13 @@ fn avro_rs_247_serde_nested_flatten_support() {
 #[should_panic(expected = "Duplicate field names found")]
 fn avro_rs_247_serde_flatten_support_duplicate_field_name() {
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct Nested {
         a: i32,
     }
 
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct Foo {
         #[serde(flatten)]
         nested: Nested,
@@ -1797,6 +1809,7 @@ fn 
avro_rs_247_serde_flatten_support_duplicate_field_name() {
 #[test]
 fn avro_rs_247_serde_flatten_support_with_skip() {
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct Nested {
         a: bool,
         #[serde(skip)]
@@ -1804,6 +1817,7 @@ fn avro_rs_247_serde_flatten_support_with_skip() {
     }
 
     #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct Foo {
         #[serde(flatten)]
         nested: Nested,
@@ -1883,6 +1897,7 @@ fn avro_rs_397_with() {
 
     #[allow(dead_code)]
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         #[avro(with)]
         #[serde(with = "module")]
@@ -1933,6 +1948,7 @@ fn avro_rs_397_with_generic() {
 
     #[allow(dead_code)]
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         #[avro(with = generic::<15>)]
         a: [u8; 15],
@@ -1967,6 +1983,7 @@ fn avro_rs_397_uuid() {
     .unwrap();
 
     #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)]
+    #[avro(tests = false)]
     struct Foo {
         #[serde(rename = "baz")]
         bar: uuid::Uuid,
@@ -1999,6 +2016,7 @@ fn avro_rs_397_derive_with_expr_lambda() {
     let expected_schema = Schema::parse_str(schema).unwrap();
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         #[avro(with = || Schema::Bytes)]
         _a: String,
@@ -2022,6 +2040,7 @@ fn avro_rs_398_transparent_with_skip() {
     #[allow(dead_code)]
     #[derive(AvroSchema)]
     #[serde(transparent)]
+    #[avro(tests = false)]
     struct Foo {
         #[serde(skip)]
         a: String,
@@ -2041,6 +2060,7 @@ fn avro_rs_401_do_not_match_typename() {
 
     #[expect(dead_code, reason = "We only check the schema")]
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         field: f32,
     }
@@ -2066,6 +2086,7 @@ fn avro_rs_401_do_not_match_typename() {
 fn avro_rs_401_supported_type_variants() {
     #[expect(dead_code, reason = "We only check the schema")]
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo<'a> {
         one: f32,
         two: std::string::String,
@@ -2170,6 +2191,7 @@ fn avro_rs_414_round_trip_char_u64_u128_i128() {
     .unwrap();
 
     #[derive(AvroSchema, Serialize, Deserialize, PartialEq, Debug, Clone)]
+    #[avro(tests = false)]
     struct Foo {
         a: char,
         b: u64,
@@ -2189,23 +2211,27 @@ fn avro_rs_414_round_trip_char_u64_u128_i128() {
 #[test]
 fn avro_rs_448_flatten_recurring_type() {
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[expect(dead_code, reason = "Only testing derived schema")]
     pub enum Color {
         G,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     pub struct A {
         pub _color: Color,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     pub struct C {
         #[serde(flatten)]
         pub _a: A,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     pub struct TestStruct {
         pub _a: Color,
         pub _c: C,
@@ -2248,29 +2274,34 @@ fn avro_rs_448_flatten_recurring_type() {
 #[test]
 fn avro_rs_448_flatten_transparent_sandwich() {
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[expect(dead_code, reason = "Only testing derived schema")]
     pub enum Color {
         G,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     pub struct A {
         pub _color: Color,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     pub struct C {
         #[serde(flatten)]
         pub _a: A,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     pub struct B {
         pub _c: C,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     pub struct TestStruct {
         pub _a: Color,
         pub _b: B,
@@ -2318,6 +2349,7 @@ fn avro_rs_448_flatten_transparent_sandwich() {
 #[test]
 fn avro_rs_448_transparent_with() {
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     pub struct TestStruct {
         #[avro(with = || Schema::Long)]
@@ -2338,12 +2370,14 @@ fn avro_rs_448_transparent_with() {
 #[test]
 fn avro_rs_448_transparent_with_2() {
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     pub struct Foo {
         _field: i32,
         _a: String,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     pub struct TestStruct {
         #[avro(with = Foo::get_schema_in_ctxt)]
@@ -2377,17 +2411,20 @@ fn avro_rs_448_transparent_with_2() {
 #[test]
 fn avro_rs_476_field_default() {
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Bar {
         _field: Box<Bar>,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[avro(default = r#"{"_field": true}"#)]
     struct Spam {
         _field: bool,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         _a: bool,
         _b: i8,
@@ -2431,12 +2468,14 @@ fn avro_rs_476_field_default() {
 #[test]
 fn avro_rs_476_field_default_false() {
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[avro(default = r#"{"_field": true}"#)]
     struct Spam {
         _field: bool,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         #[avro(default = false)]
         _a: bool,
@@ -2460,12 +2499,14 @@ fn avro_rs_476_field_default_false() {
 #[test]
 fn avro_rs_476_field_default_provided() {
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     #[avro(default = r#"{"_field": true}"#)]
     struct Spam {
         _field: bool,
     }
 
     #[derive(AvroSchema)]
+    #[avro(tests = false)]
     struct Foo {
         #[avro(default = "true")]
         _a: bool,
@@ -2542,6 +2583,7 @@ fn avro_rs_476_field_default_provided() {
 #[test]
 fn avro_rs_476_skip_serializing_fielddefault_trait_none() {
     #[derive(AvroSchema, Debug, Deserialize, Serialize)]
+    #[avro(tests = false)]
     struct T {
         x: Option<i8>,
         #[serde(skip_serializing)]
@@ -2574,6 +2616,7 @@ fn avro_rs_476_skip_serializing_fielddefault_trait_none() 
{
 #[test]
 fn avro_rs_561_transparent_struct_with_default_override() {
     #[derive(Debug, Eq, PartialEq, AvroSchema, Serialize, Deserialize)]
+    #[avro(tests = false)]
     #[serde(transparent)]
     struct T {
         #[avro(default = "42")]
@@ -2590,6 +2633,7 @@ fn avro_rs_561_transparent_struct_with_default_override() 
{
 #[test]
 fn avro_rs_569_tuple_struct() {
     #[derive(AvroSchema, Debug, PartialEq, Eq, Deserialize, Serialize)]
+    #[avro(tests = false)]
     struct T(i32, String);
 
     let schema = T::get_schema();
diff --git a/avro_derive/tests/enum.rs b/avro_derive/tests/enum.rs
index 6ef6c25..11abb57 100644
--- a/avro_derive/tests/enum.rs
+++ b/avro_derive/tests/enum.rs
@@ -72,7 +72,7 @@ where
 #[test]
 fn avro_rs_561_bare_union_untagged_empty_tuple_variant() {
     #[derive(Debug, Eq, PartialEq, AvroSchema, Serialize, Deserialize)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     #[serde(untagged)]
     enum C {
         A(),
@@ -84,7 +84,7 @@ fn avro_rs_561_bare_union_untagged_empty_tuple_variant() {
 #[test]
 fn avro_rs_561_bare_union_empty_tuple_variant() {
     #[derive(Debug, Eq, PartialEq, AvroSchema, Serialize, Deserialize)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     enum C {
         A(),
         B {},
@@ -97,6 +97,7 @@ fn avro_rs_561_bare_union_empty_tuple_variant() {
 #[test]
 fn avro_rs_569_enum_repr_default() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
+    #[avro(tests = false)]
     enum Foo {
         A,
         B,
@@ -122,7 +123,7 @@ fn avro_rs_569_enum_repr_default() {
 #[test]
 fn avro_rs_569_enum_repr_enum() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "enum")]
+    #[avro(repr = "enum", tests = false)]
     enum Foo {
         A,
         B,
@@ -148,7 +149,7 @@ fn avro_rs_569_enum_repr_enum() {
 #[test]
 fn avro_rs_569_enum_repr_record_tag_content_plain() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_tag_content")]
+    #[avro(repr = "record_tag_content", tests = false)]
     #[serde(tag = "type", content = "value")]
     enum Foo {
         A,
@@ -190,7 +191,7 @@ fn avro_rs_569_enum_repr_record_tag_content_plain() {
 #[test]
 fn avro_rs_569_enum_repr_record_tag_content_tuple() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_tag_content")]
+    #[avro(repr = "record_tag_content", tests = false)]
     #[serde(tag = "type", content = "value")]
     enum Foo {
         A,
@@ -253,7 +254,7 @@ fn avro_rs_569_enum_repr_record_tag_content_tuple() {
 #[test]
 fn avro_rs_569_enum_repr_record_tag_content_struct() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_tag_content")]
+    #[avro(repr = "record_tag_content", tests = false)]
     #[serde(tag = "type", content = "value")]
     enum Foo {
         A {},
@@ -316,7 +317,7 @@ fn avro_rs_569_enum_repr_record_tag_content_struct() {
 #[test]
 fn avro_rs_569_enum_repr_bare_union_plain() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     #[serde(untagged)]
     enum Foo {
         A,
@@ -331,7 +332,7 @@ fn avro_rs_569_enum_repr_bare_union_plain() {
 #[test]
 fn avro_rs_569_enum_repr_bare_union_tuple() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     #[serde(untagged)]
     enum Foo {
         B(String),
@@ -367,7 +368,7 @@ fn avro_rs_569_enum_repr_bare_union_tuple() {
 #[test]
 fn avro_rs_569_enum_repr_record_internally_tagged_plain() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_internally_tagged")]
+    #[avro(repr = "record_internally_tagged", tests = false)]
     #[serde(tag = "type")]
     enum Foo {
         A,
@@ -402,7 +403,7 @@ fn avro_rs_569_enum_repr_record_internally_tagged_plain() {
 )]
 fn avro_rs_569_enum_repr_record_internally_tagged_tuple_no_get_record_fields() 
{
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_internally_tagged")]
+    #[avro(repr = "record_internally_tagged", tests = false)]
     #[serde(tag = "type")]
     enum Foo {
         B(String),
@@ -414,13 +415,14 @@ fn 
avro_rs_569_enum_repr_record_internally_tagged_tuple_no_get_record_fields() {
 #[test]
 fn avro_rs_569_enum_repr_record_internally_tagged_tuple() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_internally_tagged")]
+    #[avro(repr = "record_internally_tagged", tests = false)]
     #[serde(tag = "type")]
     enum Foo {
         B(Bar),
     }
 
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
+    #[avro(tests = false)]
     struct Bar {
         spam: String,
     }
@@ -452,7 +454,7 @@ fn avro_rs_569_enum_repr_record_internally_tagged_tuple() {
 #[test]
 fn avro_rs_569_enum_repr_record_internally_tagged_struct() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_internally_tagged")]
+    #[avro(repr = "record_internally_tagged", tests = false)]
     #[serde(tag = "type")]
     enum Foo {
         A {},
@@ -512,7 +514,7 @@ fn avro_rs_569_enum_repr_record_internally_tagged_struct() {
 #[should_panic(expected = "Missing default for skipped field 'spam' of 
schema")]
 fn avro_rs_569_enum_repr_record_internally_tagged_struct_no_defaults() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "record_internally_tagged")]
+    #[avro(repr = "record_internally_tagged", tests = false)]
     #[serde(tag = "type")]
     enum Foo {
         A {},
@@ -533,7 +535,7 @@ fn 
avro_rs_569_enum_repr_record_internally_tagged_struct_no_defaults() {
 #[test]
 fn avro_rs_569_enum_repr_union_of_records_plain() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "union_of_records")]
+    #[avro(repr = "union_of_records", tests = false)]
     enum Foo {
         A,
         B,
@@ -559,7 +561,7 @@ fn avro_rs_569_enum_repr_union_of_records_plain() {
 #[test]
 fn avro_rs_569_enum_repr_union_of_records_tuple() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "union_of_records")]
+    #[avro(repr = "union_of_records", tests = false)]
     enum Foo {
         A(),
         B(String),
@@ -593,7 +595,7 @@ fn avro_rs_569_enum_repr_union_of_records_tuple() {
 #[test]
 fn avro_rs_569_enum_repr_union_of_records_struct() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "union_of_records")]
+    #[avro(repr = "union_of_records", tests = false)]
     enum Foo {
         A {},
         B {
@@ -635,7 +637,7 @@ fn avro_rs_569_enum_repr_union_of_records_struct() {
 #[test]
 fn avro_rs_569_enum_repr_bare_union_without_untagged_plain() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     enum Foo {
         A,
     }
@@ -649,7 +651,7 @@ fn 
avro_rs_569_enum_repr_bare_union_without_untagged_plain() {
 #[test]
 fn avro_rs_569_enum_repr_bare_union_without_untagged_tuple() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     enum Foo {
         B(String),
         #[serde(rename = "D")]
@@ -684,7 +686,7 @@ fn 
avro_rs_569_enum_repr_bare_union_without_untagged_tuple() {
 #[test]
 fn avro_rs_569_enum_repr_bare_union_without_untagged_tuple_same_len() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     enum Foo {
         A(String, String),
         B(i32, i32),
@@ -724,7 +726,7 @@ fn 
avro_rs_569_enum_repr_bare_union_without_untagged_tuple_same_len() {
 #[test]
 fn 
avro_rs_569_enum_repr_bare_union_without_untagged_tuple_and_struct_same_len() {
     #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)]
-    #[avro(repr = "bare_union")]
+    #[avro(repr = "bare_union", tests = false)]
     enum Foo {
         A { a: String, b: String },
         B(i32, i32),
diff --git a/avro_derive/tests/serde.rs b/avro_derive/tests/serde.rs
index 3b51074..9d612fc 100644
--- a/avro_derive/tests/serde.rs
+++ b/avro_derive/tests/serde.rs
@@ -68,6 +68,7 @@ mod container_attributes {
     #[test]
     fn avro_rs_373_rename() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(rename = "Bar")]
         struct Foo {
             a: String,
@@ -103,6 +104,7 @@ mod container_attributes {
     #[test]
     fn avro_rs_373_nested_rename() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(rename = "Bar")]
         struct Foo {
             a: String,
@@ -110,6 +112,7 @@ mod container_attributes {
         }
 
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         struct Outer {
             bar: Foo,
         }
@@ -154,6 +157,7 @@ mod container_attributes {
     #[test]
     fn avro_rs_373_rename_all() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(rename_all = "UPPERCASE")]
         struct Foo {
             a: String,
@@ -191,12 +195,14 @@ mod container_attributes {
     #[should_panic(expected = "Expected Schema::Record(name: FooFromInto)")]
     fn avro_rs_373_from_into() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(from = "FooFromInto", into = "FooFromInto")]
         struct Foo {
             a: String,
             b: i32,
         }
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         struct FooFromInto {
             a: String,
             b: i32,
@@ -251,12 +257,14 @@ mod container_attributes {
     #[should_panic(expected = r#"Missing field in record: "c""#)]
     fn avro_rs_373_from_into_different() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(from = "FooFromInto", into = "FooFromInto")]
         struct Foo {
             a: String,
             b: i32,
         }
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         struct FooFromInto {
             a: String,
             b: i32,
@@ -311,6 +319,7 @@ mod container_attributes {
     #[test]
     fn avro_rs_398_transparent() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(transparent)]
         struct Foo {
             a: String,
@@ -333,6 +342,7 @@ mod container_attributes {
     #[test]
     fn avro_rs_398_transparent_ref() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(transparent)]
         struct Foo<'a> {
             a: &'a str,
@@ -351,6 +361,7 @@ mod container_attributes {
     #[test]
     fn avro_rs_398_transparent_array() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         #[serde(transparent)]
         struct Foo {
             a: Vec<String>,
@@ -409,6 +420,7 @@ mod container_attributes {
         // Provide getters for every private field of the remote struct. The 
getter must
         // return either `T` or `&T` where `T` is the type of the field.
         #[derive(Serialize, Deserialize, AvroSchema)]
+        #[avro(tests = false)]
         #[serde(remote = "Duration")]
         struct DurationDef {
             #[serde(getter = "Duration::seconds")]
@@ -425,6 +437,7 @@ mod container_attributes {
         }
 
         #[derive(Serialize, Deserialize, AvroSchema, Debug, PartialEq, Eq)]
+        #[avro(tests = false)]
         struct Process {
             command_line: String,
 
@@ -446,6 +459,7 @@ mod variant_attributes {
     #[test]
     fn avro_rs_373_rename() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         enum Foo {
             #[serde(rename = "Three")]
             One,
@@ -471,6 +485,7 @@ mod variant_attributes {
     #[test]
     fn avro_rs_373_alias() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         enum Foo {
             #[serde(rename = "Three", alias = "One")]
             One,
@@ -496,6 +511,7 @@ mod variant_attributes {
     #[test]
     fn avro_rs_373_skip() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         enum Foo {
             #[allow(dead_code)]
             #[serde(skip)]
@@ -526,6 +542,7 @@ mod field_attributes {
     #[test]
     fn avro_rs_373_rename() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         struct Foo {
             #[serde(rename = "c")]
             a: String,
@@ -561,11 +578,13 @@ mod field_attributes {
     #[test]
     fn avro_rs_373_flatten() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         struct Nested {
             a: bool,
         }
 
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         struct Foo {
             #[serde(flatten)]
             nested: Nested,
@@ -601,6 +620,7 @@ mod field_attributes {
     #[test]
     fn avro_rs_373_skip() {
         #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)]
+        #[avro(tests = false)]
         struct Foo {
             #[serde(skip)]
             a: String,
@@ -633,6 +653,7 @@ mod field_attributes {
     fn avro_rs_397_avroschema_with_bytes() {
         #[expect(dead_code, reason = "We only care about the schema")]
         #[derive(AvroSchema)]
+        #[avro(tests = false)]
         struct TestStructWithBytes<'a> {
             #[avro(with)]
             #[serde(with = "apache_avro::serde::bytes")]


Reply via email to