Mathe S
Mathe S

Reputation: 71

ArchUnit doesnt seem to cache analyzed classes

I wrote some ArchUnit-Tests using Jupiter. I found examples that indicated, you can write your ArchUnit tests using non static methods, like:

@Test
void enforceExceptionNames() {
    classes().that()
             .areAssignableTo(Exception.class)
             .and(modifier(PUBLIC))
             .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
             .should()
             .haveNameMatching(".*Exception").orShould()
             .haveNameMatching(".*Error")
             .check(modulClasses);
}

The advantage is, that you can do things that arent possible static - like extracting the packagename using reflection at runtime and other stuff.

But performance is poor. Like 1-10 seconds depending on size.

Eitherway ArchUnit states to have all Classes cached static.

Upvotes: 3

Views: 643

Answers (2)

Manfred
Manfred

Reputation: 3062

Your initial question didn't show how modulClasses is obtained. If you do

class StandardCodeModuleTest {

    private final JavaClasses modulClasses = new ClassFileImporter().import...

then the (expensive) class file import will – usually (cf. @TestInstance) – be done for each test, without caching.

So yes, it totally makes sense to use ArchUnit's support for JUnit with @AnalyzeClasses, as you found. However, @ArchTest is not restricted to static fields or methods. You can also use non-static methods:

@ArchTest
void enforceExceptionNames(JavaClasses modulClasses) {
    classes().that()
             .areAssignableTo(Exception.class)
             .and(modifier(PUBLIC))
             .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
             .should()
             .haveNameMatching(".*Exception").orShould()
             .haveNameMatching(".*Error")
             .check(modulClasses);
}

or non-static ArchRule definitions:

@ArchTest
ArchRule enforceExceptionNames = classes()
             .that()
             .areAssignableTo(Exception.class)
             .and(modifier(PUBLIC))
             .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
             .should()
             .haveNameMatching(".*Exception").orShould()
             .haveNameMatching(".*Error");

Upvotes: 4

Mathe S
Mathe S

Reputation: 71

It semms caching ONLY occurs when using @AnalyzeClasses and @ArchTest annotated static fields or methods.

After transforming my tests to this pattern, performance skyrockets to 0.05 seconds!

@AnalyzeClasses(packages = "some.svc.gui.impl")
public class StandardCodeModuleTest extends StandardCodeTest {

    @ArchTest
    public static final ArchRule ENFORCE_EXCEPTION_NAMES = classes()
            .that()
            .areAssignableTo(Exception.class)
            .and(modifier(PUBLIC))
            .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
            .should()
            .haveNameMatching(".*Exception").orShould()
            .haveNameMatching(".*Error");

Upvotes: 3

Related Questions