agentsclimarketplace

Universal testing

Skill asong56/skills/03-build/universal/universal-testing

268 AI coding assistant skills, organized across 12 workflow layers. Sources include Anthropic official, FRM, SKC, LRN, SKA, and other mainstream AI coding frameworks.

Install
npx -y skills add asong56/skills --skill universal-testing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 17 days oldThe repository was created 17 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Language-agnostic TDD meta-skill. Inject runtime parameters (runtime, test_runner, mock_library, coverage_tool, coverage_gate) to activate language-specific idioms while keeping the core RED → GREEN → REFACTOR philosophy, assertion patterns, and testing tiers constant. Incorporates former: python-testing, kotlin-testing, rust-testing, cpp-testing, golang-testing, react-testing, csharp-testing, fsharp-testing, perl-testing.

SKILL.md

13.2 KB, as published. Nobody here has run it

universal-testing

Why This Skill Exists

Nine language-specific testing skills (python-testing, kotlin-testing, rust-testing, cpp-testing, golang-testing, react-testing, csharp-testing, fsharp-testing, perl-testing) shared an identical philosophical core — TDD cycle, assertion strategy, testing tiers, coverage gate — and differed only in tooling names. Per the Three-Principle Framework:

  • Output of language-detection = unique input of per-language test skill, with no other consumer → sequential, single-path workflowMERGE.
  • Combined token budget (core + one active config block) stays well under 5 K.

test-driven-development (universal/systematic-debugging) remains independent per the Circuit-Breaker rules: it operates under different state transitions and would balloon the prompt past 8 K if merged here.


Runtime Parameters

Call this skill by declaring params at the top of your request or by having the orchestrator inject them:

{
  "skill": "universal-testing",
  "params": {
    "runtime":        "Python",
    "test_runner":    "pytest",
    "mock_library":   "pytest-mock / unittest.mock",
    "coverage_tool":  "pytest-cov",
    "coverage_gate":  "80%"
  }
}

Quick-reference param table

runtimetest_runnermock_librarycoverage_toolCoverage default
Pythonpytestpytest-mock / unittest.mockpytest-cov80%
KotlinKotestMockKKover80%
Rustcargo test / nextestmockallcargo-llvm-cov80%
C++GoogleTest / CTestGoogleMockgcov / llvm-cov80%
Gogo testtestify/mockgo tool cover80%
React/TSVitest or Jest + RTLmswv8 / istanbul80%
C#xUnitNSubstitute / MoqCoverlet80%
F#xUnit + FsUnitNSubstituteCoverlet80%
Perlprove + Test2::V0Test::MockModuleDevel::Cover80%

If runtime is not provided, infer it from the file extension or import statements in the code under review. If still ambiguous, ask before proceeding.


Core Philosophy (Runtime-Invariant)

These rules apply regardless of language:

  1. Test behavior, not implementation. Tests assert outcomes observable from the public API — not internal state, private methods, or call counts unless the call itself is the contract.
  2. Isolate the unit. Use the declared mock_library to replace all collaborators (I/O, network, time, randomness) so tests are deterministic and fast.
  3. Coverage gate is a floor, not a goal. Hitting coverage_gate with trivial assertions is worse than 60% coverage with meaningful assertions. Critical paths require 100% branch coverage regardless of the gate.
  4. Tests are first-class code. Apply the same naming, clarity, and refactoring standards as production code.

The RED → GREEN → REFACTOR Cycle

┌─────────────────────────────────────────────────────────┐
│  1. RED    Write a failing test that expresses the      │
│            desired behavior. Run it; confirm it fails   │
│            for the right reason (not a syntax error).   │
│                          ↓                              │
│  2. GREEN  Write the minimum code to make the test      │
│            pass. Resist the urge to generalize yet.     │
│                          ↓                              │
│  3. REFACTOR  Improve the implementation while keeping  │
│               all tests green. Remove duplication,      │
│               clarify names, extract concepts.          │
│                          ↓                              │
│  4. REPEAT  Move to the next behavior unit.             │
└─────────────────────────────────────────────────────────┘

Testing Tiers

Apply these tiers in every runtime. The ratio guideline is the Testing Pyramid: many unit → fewer integration → few E2E.

Tier 1 — Unit Tests

  • Test a single function / method / class in complete isolation.
  • All external collaborators are replaced with mock_library doubles.
  • Must run in < 1 ms each; no network, no filesystem, no clock.
  • Naming: test_<unit>_<scenario>_<expected_outcome> (adapt to language convention — e.g. Go uses TestUnitScenario, Kotlin uses "unit - scenario" in Kotest).

Tier 2 — Integration Tests

  • Test the interaction between two or more real components (e.g., service + real database via Testcontainers, or HTTP client + real server on localhost).
  • Use factories or fixtures to build test data; never depend on pre-seeded production data.
  • Acceptable runtime: seconds, not minutes. Parallelize where safe.

Tier 3 — Contract / API Tests

  • Assert the public interface contract of a module or service.
  • Provider-side: verify your outputs match consumer expectations.
  • Consumer-side: verify you handle all provider response shapes.

Tier 4 — End-to-End / UI Tests

  • Exercise the full stack through a browser or CLI entry point.
  • Reserve for critical user journeys only (login, checkout, core happy path).
  • Treat flakiness as a P1 defect: flaky E2E tests erode trust in the entire suite.

Language-Specific Activation Blocks

Load only the block matching the active runtime. Ignore all others.


🐍 Python (pytest)

# Run all tests with coverage
pytest --cov={package} --cov-report=term-missing --cov-report=html

# Run a single test file
pytest tests/unit/test_service.py -v

# Run with parallel execution
pytest -n auto

Fixture pattern:

import pytest

@pytest.fixture
def user_service(mocker):
    repo = mocker.Mock(spec=UserRepository)
    return UserService(repo)

def test_find_user_returns_none_when_not_found(user_service, mocker):
    mocker.patch.object(user_service._repo, "get", return_value=None)
    assert user_service.find("[email protected]") is None

Parametrize pattern:

@pytest.mark.parametrize("email,valid", [
    ("[email protected]", True),
    ("bad-email", False),
    ("", False),
])
def test_email_validation(email, valid):
    assert validate_email(email) == valid

Coverage gate command:

pytest --cov={package} --cov-fail-under=80

🟣 Kotlin (Kotest + MockK)

// FunSpec example (preferred for unit tests)
class UserServiceTest : FunSpec({
    val repo = mockk<UserRepository>()
    val service = UserService(repo)

    test("returns null when user not found") {
        every { repo.findByEmail("[email protected]") } returns null
        service.find("[email protected]") shouldBe null
    }
})

Coroutine testing:

test("suspends until result is ready") {
    coEvery { repo.fetchAsync(any()) } returns User("alice")
    runTest { service.fetchUser("alice") shouldBe User("alice") }
}

Coverage gate command:

./gradlew koverVerify   # fails build if < 80%

🦀 Rust (cargo test + mockall)

#[cfg(test)]
mod tests {
    use super::*;
    use mockall::predicate::*;

    #[test]
    fn returns_error_on_missing_user() {
        let mut repo = MockUserRepository::new();
        repo.expect_find().with(eq("ghost")).returning(|_| None);
        let svc = UserService::new(repo);
        assert!(svc.get_user("ghost").is_err());
    }
}

Async test:

#[tokio::test]
async fn fetch_user_resolves() {
    // ...
}

Coverage gate command:

cargo llvm-cov --fail-under-lines 80

⚙️ C++ (GoogleTest + GoogleMock)

// CMakeLists.txt: add_executable(tests ...) + target_link_libraries(tests GTest::gtest_main gmock)

TEST(UserServiceTest, ReturnsFalseWhenUserNotFound) {
    MockUserRepository repo;
    EXPECT_CALL(repo, FindByEmail("[email protected]")).WillOnce(Return(std::nullopt));
    UserService svc{repo};
    EXPECT_FALSE(svc.Find("[email protected]").has_value());
}

Parametrized test:

INSTANTIATE_TEST_SUITE_P(
    EmailValidation, EmailTest,
    testing::Values(
        std::make_tuple("[email protected]", true),
        std::make_tuple("bad", false)
    )
);

Coverage gate command:

cmake -DCMAKE_BUILD_TYPE=Coverage .. && make && ctest
lcov --summary coverage.info | grep "lines"   # manual check against gate

🐹 Go (go test + testify)

func TestUserService_Find_ReturnsNilWhenMissing(t *testing.T) {
    repo := new(MockUserRepository)
    repo.On("FindByEmail", "[email protected]").Return(nil, nil)
    svc := NewUserService(repo)
    result, err := svc.Find("[email protected]")
    assert.NoError(t, err)
    assert.Nil(t, result)
}

Table-driven pattern (idiomatic Go):

tests := []struct{ email string; want bool }{
    {"[email protected]", true},
    {"bad", false},
}
for _, tc := range tests {
    t.Run(tc.email, func(t *testing.T) {
        assert.Equal(t, tc.want, ValidateEmail(tc.email))
    })
}

Coverage gate command:

go test ./... -coverprofile=coverage.out
go tool cover -func=coverage.out | grep total   # check vs gate manually

⚛️ React / TypeScript (Vitest + RTL + MSW)

// Test what the user sees, not implementation details
test("shows error message on login failure", async () => {
    server.use(http.post("/api/login", () => HttpResponse.json({ error: "Bad credentials" }, { status: 401 })));
    render(<LoginForm />, { wrapper: Providers });
    await userEvent.type(screen.getByLabelText(/email/i), "[email protected]");
    await userEvent.click(screen.getByRole("button", { name: /log in/i }));
    expect(await screen.findByRole("alert")).toHaveTextContent(/bad credentials/i);
});

Accessibility assertion:

test("form has no accessibility violations", async () => {
    const { container } = render(<LoginForm />, { wrapper: Providers });
    const results = await axe(container);
    expect(results).toHaveNoViolations();
});

Coverage gate command:

vitest run --coverage --coverage.thresholds.lines=80

🔷 C# (xUnit + NSubstitute + Coverlet)

public class UserServiceTests
{
    [Fact]
    public async Task FindAsync_ReturnsNull_WhenUserNotFound()
    {
        var repo = Substitute.For<IUserRepository>();
        repo.FindByEmailAsync("[email protected]").Returns((User?)null);
        var svc = new UserService(repo);
        var result = await svc.FindAsync("[email protected]");
        result.Should().BeNull();
    }

    [Theory]
    [InlineData("[email protected]", true)]
    [InlineData("bad", false)]
    public void ValidateEmail_ReturnsExpected(string email, bool expected) =>
        EmailValidator.IsValid(email).Should().Be(expected);
}

Coverage gate command:

dotnet test /p:CollectCoverage=true /p:Threshold=80

🟦 F# (xUnit + FsUnit + FsCheck)

[<Fact>]
let ``find returns None when user missing`` () =
    let repo = Substitute.For<IUserRepository>()
    repo.FindByEmail("[email protected]").Returns(None) |> ignore
    let svc = UserService(repo)
    svc.Find("[email protected]") |> should equal None

// Property-based test with FsCheck
[<Property>]
let ``non-empty strings are never equal to None result`` (email: NonEmptyString) =
    // ...

🐪 Perl (Test2::V0 + prove)

use Test2::V0;
use Test::MockModule;

my $mock = mock 'UserRepository' => (
    override => [find_by_email => sub { undef }],
);
my $svc = UserService->new(repo => UserRepository->new);
is $svc->find("ghost\@x.com"), undef, "returns undef when user not found";
done_testing;

Coverage gate command:

cover -test -report html
# Check Devel::Cover output for statement coverage >= 80%

Workflow Checklist

Before marking a TDD cycle complete, verify:

  • Test name clearly describes scenario and expected outcome
  • Test fails (RED) before implementation is written
  • Test passes (GREEN) with minimal implementation
  • No implementation details leaked into assertions
  • All external I/O is mocked / stubbed
  • Edge cases covered: null/empty input, boundary values, error paths
  • coverage_tool run; gate met or gap documented with rationale
  • Test is deterministic: passes identically on first and hundredth run

Migration Notes

Deprecated skillReplaced byruntime param
python-testinguniversal-testing"Python"
kotlin-testinguniversal-testing"Kotlin"
rust-testinguniversal-testing"Rust"
cpp-testinguniversal-testing"C++"
golang-testinguniversal-testing"Go"
react-testinguniversal-testing"React/TS"
csharp-testinguniversal-testing"C#"
fsharp-testinguniversal-testing"F#"
perl-testinguniversal-testing"Perl"

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.