Why can't I see the function which was generated by attribute macro expansion

Hello everyone. I'm new to macros so I might be missing some silly mistake I made. Need help.

I have an integration test crate (separate file) for which I have disabled the test harness:

Cargo.toml:

[[test]]
name = "command_handlers"
harness = false

In the test file, I've defined the main function and I want to call the test function that is generated by the sqlx::test macro expansion:

tests/command_handlers.rs:

fn main() {
  test_help_sends_expected_message();
}

#[sqlx::test]
async fn test_help_sends_expected_message(db_pool: PgPool) {
}

The attribute-annotated function expands into the following:

#[::core::prelude::v1::test]
fn test_help_sends_expected_message() {
    async fn test_help_sends_expected_message(db_pool: PgPool) {
        {}
    }
    let mut args = ::sqlx::testing::TestArgs::new("module::path::test_help_sends_expected_message");
    args.migrator(&::sqlx::migrate::Migrator {
        migrations: ::std::borrow::Cow::Borrowed(&[
            ::sqlx::migrate::Migration {
                version: 20240704180811i64,
                description: ::std::borrow::Cow::Borrowed("create lunch polls"),
                migration_type: ::sqlx::migrate::MigrationType::ReversibleUp,
                sql: ::std::borrow::Cow::Borrowed(""),
                checksum: ::std::borrow::Cow::Borrowed(&[
                    148u8, 157u8, 107u8, 164u8, 196u8, 149u8, 223u8, 246u8, 85u8, 175u8, 230u8, 7u8, 93u8, 87u8, 155u8,
                    176u8, 170u8, 101u8, 140u8, 195u8, 35u8, 249u8, 146u8, 133u8, 10u8, 33u8, 78u8, 167u8, 137u8,
                    219u8, 235u8, 103u8, 70u8, 70u8, 107u8, 239u8, 124u8, 152u8, 60u8, 158u8, 120u8, 137u8, 82u8, 40u8,
                    111u8, 195u8, 6u8, 243u8,
                ]),
            },
            ::sqlx::migrate::Migration {
                version: 20240704180811i64,
                description: ::std::borrow::Cow::Borrowed("create lunch polls"),
                migration_type: ::sqlx::migrate::MigrationType::ReversibleDown,
                sql: ::std::borrow::Cow::Borrowed(""),
                checksum: ::std::borrow::Cow::Borrowed(&[
                    158u8, 150u8, 79u8, 250u8, 239u8, 246u8, 73u8, 172u8, 236u8, 38u8, 185u8, 118u8, 123u8, 5u8, 231u8,
                    1u8, 93u8, 154u8, 214u8, 151u8, 143u8, 79u8, 173u8, 72u8, 146u8, 250u8, 102u8, 65u8, 9u8, 220u8,
                    144u8, 197u8, 174u8, 130u8, 95u8, 1u8, 109u8, 95u8, 208u8, 223u8, 18u8, 126u8, 156u8, 191u8, 56u8,
                    230u8, 72u8, 164u8,
                ]),
            },
        ]),
        ..::sqlx::migrate::Migrator::DEFAULT
    });
    args.fixtures(&[]);
    let f: fn(_) -> _ = test_help_sends_expected_message;
    ::sqlx::testing::TestFn::run_test(f, args)
}

But I cannot refer to the enclosing test_help_sends_expected_message generated by the macro from main: I get an error cannot find function test_help_sends_expected_message in this scope.

Can this be fixed?

Could this be because I'm trying, in fact, to refer to the internal (async) function with this name and it's hidden because it's defined inside of an enclosing function (which is, in turn, is impossible to call)?

The problem is a property of the #[test] attribute — it discards the function (like #[cfg]) if tests are not being built. The interesting part, which I just learned, is that this is not controlled by cfg(test), but rather by whether --test was passed to rustc, and hence by the state of the harness flag too.

You will have to find a solution to your problem that does not involve functions marked with #[test].

1 Like