Skip to content

Throw error from reporter directly for single reporter #157

Description

@muehmar

Is it possible to throw the error from a reporter directly in case there is only one compatible reporter instead of catching it and wrap it into the custom SnapshotMatchException?

The reason behind this question: IDE's (in my case IntelliJ IDEA) may have the ability to provide a diff for failing tests directly (without the need to find the *snap.debug file manually and compare it with the current file) but only if the error is well known (I guess). So currently, I can add my own reporter which uses assertions from junit5 for which IntelliJ could provide the diff but as the error is wrapped in the SnapshotMatchException, Intellij wont provide any diff.

Activity

  1. jackmatt2 commented on Aug 8, 2023

    @jackmatt2
    Collaborator

    In theory a check for a single error could happen here:

    https://github.com/origin-energy/java-snapshot-testing/blob/master/java-snapshot-testing-core/src/main/java/au/com/origin/snapshots/SnapshotContext.java#L91-L101

    I'm not sure we'd want to do it though and it might be able to be done another way.

    Have a look at this thread: #44 (comment)

    Specifically using https://github.com/skyscreamer/JSONassert

  2. muehmar commented on Aug 8, 2023

    @muehmar
    Author

    Instead of throwing the error directly in case of single reporters, one could also unwrap the SnapshotMatchException in a test. For JUnit5 one can implement the InvocationInterceptor, where one can catch the SnapshotMatchException and unwrap it in case of a single failure. As your SnapshotExtension class is not final, I was able to extend this class and implement the method to unwrap it (and use DiffSnapshotExtension instead of SnapshotExtension):

    public class DiffSnapshotExtension extends SnapshotExtension
        implements InvocationInterceptor {
    
      @Override
      public void interceptTestMethod(
          final Invocation<Void> invocation,
          final ReflectiveInvocationContext<Method> invocationContext,
          final ExtensionContext extensionContext)
          throws Throwable {
        try {
          invocation.proceed();
        } catch (final SnapshotMatchException e) {
          final List<Throwable> failures = e.getFailures();
          if (failures.size() == 1) {
            throw failures.get(0);
          }
          throw e;
        }
      }
    }
    

    I suspect, the SnapshotExtension class is not really designed to be extended, the alternative would be to not inherit from SnapshotExtension but one has to annotate each test class with two extensions.

    Is there anything which you can think of to add support to achieve this? Probably one could provide an opt-in mechanism to map the SnapshotMatchException to a custom one? If no mapping is defined, the behaviour is the same as now.

  3. muehmar commented on Aug 31, 2023

    @muehmar
    Author

    Any thoughts about this? The mentioned interceptor works, one has to override also another method to intercept also parameterized tests. I implemented this in a separate Extension, so I need to add for every snapshot test class two extensions which works but is not as convenient as before (and all existing snapshot test classes need to get modified).

    So I really would appreciate any support in the library concerning this. Adding the possibility to specify a custom Exception Mapper (the way it is done also for Reporters etc) does not seem to be a big deal or is it? The custom Exception mapper is just used to map the created SnapshotMatchException before it is thrown. If no Exception Mapper is configured (or a standard implementation which simply does not do any mapping) will just throw the SnapshotMatchException as is.

    If you are pretty busy I could also implement the changes and open a PR if you think this is something you want to support?

  4. jackmatt2 commented on Aug 8, 2024

    @jackmatt2
    Collaborator

    I would be happy for a PR that achieves this. Just needs to remain backward compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions