Running tests depending on the environment

I have written a library which parses and outputs data in a specific format to file.

Currently I produce by test code from an external tool which is an existing implementation of this file format but in Java. My Rust code parses this, round trips it and so forth. I would also like to try reparsing the code with the Java library as a test.

As I do not want people using my library to be dependent on the java library, I generate the test input files out and put the generated files into the git repository. Similarly, for reparsing, I only want to do this if the external dependency is already there.

But I can't think how to run tests only under some circumstances. Is there any way of specifying "run this test if Java is available on the machine, otherwise don't"?

Inside of your test you could check at run time, whether a dependency like java exist and if not, abort the test. Crude example:

#[test]
fn test_that_needs_java() {
    match std::process::Command::new("which").arg("java").status() {
        Ok(s) if s.success() => {}, 
        _ => {
            println!("java not found, aborting test");
            return;
        }
    }
    
    // here test code
}

That leaves the test running,and passing, when it should show up as ignored.

The best I have got at the moment is to put all the tests behind a specific feature gate. So, then they have to be turned on. I guess that is not such a bad thing.

I wonder if this can be done with a build script. Putting the java probe from above in the build script:

fn main() {
    println!("cargo::rerun-if-changed=build.rs");

    println!("cargo::rustc-check-cfg=cfg(java)");
    match std::process::Command::new("which").arg("java").status() {
        Ok(s) if s.success() => {
            println!("cargo::rustc-cfg=java");
        }, 
        _ => {}
    }
}

may allow you to ignore your java-specific tests like this:

#[cfg(all(test, java))]
mod java_tests {
    // ...
}

or if you want to show the tests as ignored in your console:

#[test]
#[cfg_attr(not(java), ignore)]
fn test_that_needs_java() {}
2 Likes

That looks like a fairly good solution, I think. I will give it a go and report back!