All skills
lexler avatar

/approval-tests

@83aee6a
by Lada Kesselerlexler/skill-factory238 stars
61

Writes approval tests (snapshot/golden master testing) for Python, JavaScript/TypeScript, or Java. Use when verifying complex output, characterization testing legacy code, testing combinations, or working with .approved/.received files.

Use this Skill: https://skilld.dev/gh/lexler/skill-factory/approval-tests

This session only. Nothing lands on disk.

referencesjavaapi.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Java ApprovalTests API

Contents

For scrubbers, see scrubbers.md. For multiple approvals per test, see advanced.md. For console output verification, see logging.md.

Imports

import org.approvaltests.Approvals;
import org.approvaltests.core.Options;
import org.approvaltests.JsonApprovals;
import org.approvaltests.combinations.CombinationApprovals;

Core Methods

Approvals.verify()

Approvals.verify(String response)
Approvals.verify(String response, Options options)
Approvals.verify(Object object)
Approvals.verify(Object object, Options options)
Approvals.verify("Hello World");
Approvals.verify(myObject.toString());

Approvals.verifyAll()

Approvals.verifyAll(String label, T[] array)
Approvals.verifyAll(T[] values, Function1<T, String> formatter)
Approvals.verifyAll(String header, T[] values, Function1<T, String> formatter)
String[] names = {"Alice", "Bob", "Charlie"};
Approvals.verifyAll("names", names);

Approvals.verifyAll("users", users, u -> u.getName() + ": " + u.getEmail());

XML/HTML Verification

Approvals.verifyXml(String xml)
Approvals.verifyXml(String xml, Options options)
Approvals.verifyHtml(String html)
Approvals.verifyHtml(String html, Options options)

Exception Verification

Approvals.verifyException(() -> {
    throw new RuntimeException("Expected error");
});

JsonApprovals

JsonApprovals.verifyJson(String json)
JsonApprovals.verifyAsJson(Object object)
JsonApprovals.verifyAsJson(Object object, Options options)
User user = new User("Alice", 30);
JsonApprovals.verifyAsJson(user);

CombinationApprovals

Test all combinations of inputs:

CombinationApprovals.verifyAllCombinations(
    (size, color) -> createProduct(size, color),
    new String[]{"S", "M", "L"},
    new String[]{"red", "blue"}
);

Pairwise testing (fewer combinations):

CombinationApprovals.verifyBestCoveringPairs(
    (a, b, c) -> process(a, b, c),
    params1, params2, params3
);

Skip invalid combinations:

CombinationApprovals.verifyAllCombinations(
    (a, b) -> {
        if (invalidCombo(a, b)) throw new SkipCombination();
        return process(a, b);
    },
    params1, params2
);

StoryBoard

Captures state progression over multiple frames. Use for state machines, animations, multi-step workflows.

import org.approvaltests.Approvals;
import org.approvaltests.StoryBoard;

StoryBoard story = new StoryBoard();
story.add(game);
story.addFrames(3, game::advance);
Approvals.verify(story);

Output stacks frames vertically:

Initial:
room: entrance
inventory: []

Frame #1:
room: hallway
inventory: []

Frame #2:
room: armory
inventory: [sword]

With descriptions and context manager:

import org.approvaltests.StoryBoardApprovals;

try (VerifiableStoryBoard story = StoryBoardApprovals.verifyStoryboard()) {
    story.addDescription("Game state progression");
    story.add(game);
    story.addFrame("After move", game.advance());
    story.addDescriptionWithData("picked up", game.pickUp("sword"));
    story.addFrames(2, game::advance);
}

Options Class

Options options = new Options()
    .withReporter(new Junit5Reporter())
    .withScrubber(DateScrubber.getScrubberFor("00:00:00"))
    .forFile().withExtension(".json");

Approvals.verify(result, options);

Methods

  • withReporter(reporter) - Set failure reporter
  • withScrubber(scrubber) - Set scrubber function
  • inline(expected) - Use inline approvals
  • forFile().withExtension(".ext") - Set file extension
  • forFile().withBaseName(name) - Custom base filename
  • forFile().withAdditionalInformation(info) - Add info to filename

Reporters

See reporters.md for full reporter reference.

Common reporters: Junit5Reporter, IntelliJReporter, QuietReporter, ClipboardReporter

// Via annotation
@UseReporter(Junit5Reporter.class)
public class MyTest { }

// Via Options
Approvals.verify(result, new Options().withReporter(new Junit5Reporter()));

Verifiable Interface

For custom objects:

public class MyClass implements Verifiable {
    @Override
    public VerifyParameters getVerifyParameters(Options options) {
        return new VerifyParameters(
            options.createWriter(this.toString()),
            options.forFile().getNamer(),
            options.getReporter()
        );
    }
}

// Then just:
Approvals.verify(myObject);

File Operations

Approvals.verifyEachFileInDirectory(new File("output/"));
Approvals.verifyEachFileInDirectory(directory, file -> file.getName().endsWith(".json"));

Database Results

ResultSet rs = statement.executeQuery("SELECT * FROM users");
Approvals.verify(rs);

Source: SKILL.md on GitHub

1 warning6d4 checks · Risk SAFE
  • Gen Agent Trust Hub6d

    The skill provides instructions and patterns for implementing approval testing (snapshot testing) across multiple programming languages. It includes capabilities for file system operations, command execution for testing CLI tools, and launching external diff reporters, which are consistent with the skill's purpose. The analysis identified an indirect prompt injection surface when verifying external or untrusted data.

  • Socket6d

    No alerts

  • Snyk6d

    Risk: LOW · No issues

  • Runlayer7mo

    25/25 files flagged

Signed by skilld at 83aee6a. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 8 months ago

README badge

README badge for lexler/skill-factory/approval-tests