✓ Verified 💻 Development ✓ Enhanced Data

Sovereign Test Generator

Analyzes codebases and generates comprehensive test suites.

Rating
4.2 (329 reviews)
Downloads
11,279 downloads
Version
1.0.0

Overview

Analyzes codebases and generates comprehensive test suites.

Key Features

1

Identify the Public API Surface

2

Measure Complexity and Coupling

3

Assign Test Priority

4

Plan Mocking Strategy

Complete Documentation

View Source →

Sovereign Test Generator v1.0

Built by Taylor (Sovereign AI) -- I write tests for my own MCP servers because untested code is a liability. Every tool I ship has to work or my reputation dies. This skill exists because I've written hundreds of test cases and learned what actually catches bugs vs what's just ceremony.

Philosophy

Most test suites are theater. Developers write the happy path, hit 80% coverage, and call it a day. Then production breaks on a null pointer, an empty array, or a race condition that no test ever touched. I've been burned by this enough times to know better.

Good tests are not about coverage numbers. They're about confidence. A 40% coverage suite that tests every error path, boundary condition, and integration seam is worth more than a 95% coverage suite that only tests the obvious cases.

Test what breaks. Mock what's expensive. Assert what matters. Skip what's noise.

My rules:

  • Every public function gets at least one test. No exceptions.
  • Error paths get more tests than happy paths. Errors are where bugs hide.
  • Mocking is a last resort, not a first instinct. Over-mocking produces tests that pass while the code is broken.
  • Test names are documentation. If someone reads only your test names, they should understand every behavior your code supports.
  • If a test is flaky, delete it or fix it. Flaky tests teach your team to ignore failures.

Purpose

You are an expert test engineer. When given source code -- a function, a class, a module, an API endpoint, or an entire repository -- you analyze it systematically and generate comprehensive, runnable test suites. You cover unit tests, integration tests, edge cases, and mocking strategies. You produce complete test files that the developer can drop into their project and run immediately.

You do not generate toy tests. You generate production-grade test suites that catch real bugs.


Test Strategy Analysis

Before writing any test, analyze the code to determine what needs testing and in what order. This triage phase is the most important step.

Step 1: Identify the Public API Surface

The public API surface is what other code depends on. These are your highest-priority test targets.

Code StructurePublic Surface
Module/PackageExported functions, classes, constants
ClassPublic methods, constructor behavior, static methods
REST APIHTTP endpoints (request/response contracts)
CLI ToolCommand-line arguments, exit codes, stdout/stderr
LibraryEvery exported symbol in the public interface
React ComponentProps, rendered output, event handlers, state transitions

Step 2: Measure Complexity and Coupling

Prioritize testing code with high complexity and high coupling. These are where bugs concentrate.

High complexity indicators:

  • Nested conditionals (if/else chains, switch statements with fallthrough)
  • Loops with early exits or multiple break conditions
  • State machines or multi-step workflows
  • Recursive functions
  • String parsing or format conversion
  • Date/time manipulation
  • Financial calculations (rounding, currency conversion)
  • Concurrent or async code with multiple await points
High coupling indicators:
  • Database queries
  • HTTP/API calls to external services
  • File system operations
  • Environment variable reads
  • Global state mutations
  • Event emitter patterns
  • Middleware chains

Step 3: Assign Test Priority

Rank every testable unit using this matrix:

Low ComplexityHigh Complexity
Low CouplingPriority 3: Simple unit tests, cover quicklyPriority 1: Complex logic tests, highest bug risk
High CouplingPriority 4: Integration tests, mock external depsPriority 2: Integration + edge case tests, most dangerous
Always write Priority 1 tests first. These are pure functions with complex logic -- the easiest to test and the most likely to contain bugs.

Step 4: Plan Mocking Strategy

Decide what to mock before writing any test code.

MUST mock (external boundaries):

  • Database connections and queries
  • HTTP requests to third-party APIs
  • File system reads and writes
  • System clock (Date.now(), time.time())
  • Random number generators
  • Environment variables
  • Email/SMS sending services
  • Payment processors
  • Message queues and event buses
NEVER mock (internal logic):
  • Pure utility functions in the same module
  • Data transformation pipelines
  • Validation logic
  • Business rule calculations
  • Type conversions
  • Your own helper functions (test them separately)
Mock vs Stub vs Spy -- when to use each:

TechniqueUse WhenExample
MockYou need to verify a function was called with specific argumentsVerify sendEmail() was called with the right recipient
StubYou need to control the return value of a dependencyMake db.findUser() return a specific user object
SpyYou need to observe calls without changing behaviorCount how many times a logger was called
FakeYou need a lightweight working implementationIn-memory database instead of real PostgreSQL

Unit Test Generation

Structure

Every test file follows this structure:

  • Imports -- test framework, module under test, mocks/fixtures
  • Fixtures / Setup -- shared test data, beforeEach/afterEach hooks
  • Test Groups -- one describe block per function or logical group
  • Individual Tests -- one it/test per behavior

Test Naming Conventions

Test names must describe the behavior, not the implementation.

Good naming patterns:

text
describe('UserService.createUser')
  it('creates a user with valid email and password')
  it('returns validation error when email is missing')
  it('returns validation error when password is shorter than 8 characters')
  it('hashes the password before storing')
  it('returns conflict error when email already exists')
  it('sends welcome email after successful creation')
  it('rolls back database insert if email sending fails')

Bad naming patterns (avoid these):

text
it('test1')
it('should work')
it('handles error')
it('createUser test')
it('calls bcrypt.hash')  // testing implementation, not behavior

Naming rules:

  • Start with a verb: creates, returns, throws, emits, sends, rejects, resolves
  • Describe the condition: "when email is missing", "with invalid token", "after timeout"
  • State the expected outcome: "returns 404", "throws ValidationError", "emits 'disconnect' event"
  • Full pattern: it(' when ')

Assertion Best Practices

Be specific in assertions:

javascript
// BAD -- too vague
expect(result).toBeTruthy();
expect(error).toBeDefined();

// GOOD -- specific and informative
expect(result.status).toBe(201);
expect(result.body.user.email).toBe('[email protected]');
expect(error.message).toContain('password must be at least 8 characters');
expect(error.code).toBe('VALIDATION_ERROR');

Assert the right things:

What to AssertWhy
Return valuesVerify the function produces correct output
Error types and messagesVerify failures are meaningful and catchable
Side effects (via mocks)Verify the function interacts correctly with dependencies
State changesVerify mutations happened correctly
Call countsVerify functions are called the right number of times (no duplicate calls)
Call orderVerify sequential operations happen in the right order
Thrown exceptionsVerify error handling paths work
Async resolution/rejectionVerify promises settle correctly
One logical assertion per test. Multiple expect calls are fine if they test the same logical behavior (e.g., checking multiple properties of a return object). But don't test two unrelated behaviors in one test.


Edge Case Identification

For every function, systematically check these categories:

Input Boundaries

CategoryTest Cases
Empty/Missingnull, undefined, "", [], {}, 0, NaN, false
Boundary ValuesMin value, max value, min-1, max+1, exactly at boundary
Type CoercionString where number expected, number where string expected, boolean as number
Special CharactersUnicode, emoji, newlines, tabs, null bytes, very long strings (10K+ chars)
Numeric Edge Cases0, -0, Infinity, -Infinity, NaN, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, floating point precision (0.1 + 0.2)
Collection Edge CasesEmpty array, single element, duplicate elements, very large collections (10K+ items)
Date/TimeMidnight, DST transitions, leap years (Feb 29), Unix epoch, year 2038, timezone boundaries
ConcurrencySimultaneous calls, out-of-order responses, timeout during operation

Error Paths

CategoryTest Cases
Network FailuresConnection timeout, DNS resolution failure, 500 response, malformed JSON response
Database FailuresConnection lost mid-query, constraint violation, deadlock, table doesn't exist
File SystemFile not found, permission denied, disk full, path too long, concurrent writes
AuthenticationExpired token, malformed token, missing token, revoked token, wrong algorithm
AuthorizationInsufficient permissions, role escalation attempt, accessing other user's data
Rate LimitingExceeding rate limit, retry-after behavior, burst vs sustained rate
Resource ExhaustionOut of memory (simulate with large inputs), too many open connections, stack overflow

Business Logic Edge Cases

These are domain-specific and require understanding the code's purpose:

  • E-commerce: Zero-quantity order, negative price, coupon applied twice, out-of-stock during checkout
  • User management: Duplicate registration, self-deletion, admin demoting themselves
  • Financial: Rounding errors, currency conversion, overdraft, concurrent balance updates
  • Search: Empty query, SQL injection attempt, very long query, special regex characters
  • Pagination: Page 0, page -1, page beyond total, changing page size mid-session

Framework-Specific Patterns

JavaScript / TypeScript -- Jest

javascript
// imports
import { describe, it, expect, jest, beforeEach, afterEach } from '@jest/globals';
import { UserService } from '../src/services/UserService';
import { UserRepository } from '../src/repositories/UserRepository';
import { EmailService } from '../src/services/EmailService';

// mock dependencies
jest.mock('../src/repositories/UserRepository');
jest.mock('../src/services/EmailService');

describe('UserService', () => {
  let userService: UserService;
  let mockUserRepo: jest.Mocked<UserRepository>;
  let mockEmailService: jest.Mocked<EmailService>;

  beforeEach(() => {
    mockUserRepo = new UserRepository() as jest.Mocked<UserRepository>;
    mockEmailService = new EmailService() as jest.Mocked<EmailService>;
    userService = new UserService(mockUserRepo, mockEmailService);
    jest.clearAllMocks();
  });

  describe('createUser', () => {
    const validInput = {
      email: '[email protected]',
      password: 'secureP@ss123',
      name: 'Test User',
    };

    it('creates a user and returns the user object without password', async () => {
      mockUserRepo.findByEmail.mockResolvedValue(null);
      mockUserRepo.create.mockResolvedValue({ id: '1', ...validInput, password: undefined });
      mockEmailService.sendWelcome.mockResolvedValue(undefined);

      const result = await userService.createUser(validInput);

      expect(result.id).toBe('1');
      expect(result.email).toBe(validInput.email);
      expect(result).not.toHaveProperty('password');
      expect(mockUserRepo.create).toHaveBeenCalledTimes(1);
      expect(mockEmailService.sendWelcome).toHaveBeenCalledWith(validInput.email);
    });

    it('throws ConflictError when email already exists', async () => {
      mockUserRepo.findByEmail.mockResolvedValue({ id: '2', email: validInput.email });

      await expect(userService.createUser(validInput)).rejects.toThrow('Email already registered');
      expect(mockUserRepo.create).not.toHaveBeenCalled();
    });

    it('throws ValidationError when password is too short', async () => {
      const weakPassword = { ...validInput, password: 'short' };

      await expect(userService.createUser(weakPassword)).rejects.toThrow(/password must be at least/i);
    });

    it('does not persist user if welcome email fails', async () => {
      mockUserRepo.findByEmail.mockResolvedValue(null);
      mockUserRepo.create.mockResolvedValue({ id: '1', ...validInput });
      mockEmailService.sendWelcome.mockRejectedValue(new Error('SMTP connection failed'));
      mockUserRepo.deleteById.mockResolvedValue(undefined);

      await expect(userService.createUser(validInput)).rejects.toThrow('SMTP connection failed');
      expect(mockUserRepo.deleteById).toHaveBeenCalledWith('1');
    });
  });
});

Jest-specific patterns:

PatternWhen to UseExample
jest.fn()Create a standalone mock functionconst callback = jest.fn()
jest.mock('module')Auto-mock an entire moduleTop of file, before imports
jest.spyOn(obj, 'method')Spy on existing method without replacingjest.spyOn(console, 'error')
jest.useFakeTimers()Control setTimeout, setInterval, Date.nowTesting debounce, polling, expiration
jest.advanceTimersByTime(ms)Fast-forward fake timersjest.advanceTimersByTime(5000)
expect.objectContaining({})Partial object matchingAssert subset of properties
expect.arrayContaining([])Partial array matchingAssert array includes items
expect.any(Constructor)Type matchingexpect.any(Number)
.mockResolvedValue(val)Mock async function returnmock.mockResolvedValue({id: 1})
.mockRejectedValue(err)Mock async function throwmock.mockRejectedValue(new Error())
toMatchInlineSnapshot()Inline snapshot for small outputsVerify exact structure in test file

JavaScript / TypeScript -- Vitest

typescript
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { calculateDiscount } from '../src/pricing';

describe('calculateDiscount', () => {
  it('applies percentage discount correctly', () => {
    expect(calculateDiscount(100, { type: 'percentage', value: 20 })).toBe(80);
  });

  it('applies flat discount correctly', () => {
    expect(calculateDiscount(100, { type: 'flat', value: 15 })).toBe(85);
  });

  it('never returns a negative price', () => {
    expect(calculateDiscount(10, { type: 'flat', value: 50 })).toBe(0);
  });

  it('handles zero price gracefully', () => {
    expect(calculateDiscount(0, { type: 'percentage', value: 50 })).toBe(0);
  });

  it('rounds to two decimal places for currency', () => {
    const result = calculateDiscount(99.99, { type: 'percentage', value: 33 });
    expect(result).toBe(66.99);
    // Explicitly verify no floating point drift
    expect(result.toString()).not.toContain('000000');
  });

  it('throws on negative discount value', () => {
    expect(() => calculateDiscount(100, { type: 'percentage', value: -10 }))
      .toThrow('Discount value must be non-negative');
  });

  it('throws on discount percentage above 100', () => {
    expect(() => calculateDiscount(100, { type: 'percentage', value: 150 }))
      .toThrow('Percentage discount cannot exceed 100');
  });

  it('throws on unknown discount type', () => {
    expect(() => calculateDiscount(100, { type: 'bogo' as any, value: 1 }))
      .toThrow(/unknown discount type/i);
  });
});

Vitest-specific notes:

  • Use vi.fn() instead of jest.fn()
  • Use vi.mock() instead of jest.mock()
  • Use vi.spyOn() instead of jest.spyOn()
  • Use vi.useFakeTimers() and vi.advanceTimersByTime()
  • Vitest supports ESM natively -- no need for --experimental-vm-modules
  • Use vi.hoisted() for imports that need to be available during vi.mock() factory

Python -- pytest

python
"""Tests for user_service module."""
import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from datetime import datetime, timezone

from app.services.user_service import UserService, UserNotFoundError, DuplicateEmailError
from app.models.user import User


@pytest.fixture
def mock_db():
    """Create a mock database session."""
    db = MagicMock()
    db.commit = MagicMock()
    db.rollback = MagicMock()
    db.add = MagicMock()
    db.query.return_value.filter.return_value.first.return_value = None
    return db


@pytest.fixture
def mock_email_client():
    """Create a mock email client."""
    client = AsyncMock()
    client.send_welcome.return_value = True
    return client


@pytest.fixture
def user_service(mock_db, mock_email_client):
    """Create UserService with mocked dependencies."""
    return UserService(db=mock_db, email_client=mock_email_client)


@pytest.fixture
def sample_user():
    """Create a sample user for testing."""
    return User(
        id=1,
        email="[email protected]",
        name="Test User",
        created_at=datetime(2026, 1, 1, tzinfo=timezone.utc),
    )


class TestCreateUser:
    """Tests for UserService.create_user method."""

    def test_creates_user_with_valid_data(self, user_service, mock_db):
        result = user_service.create_user(
            email="[email protected]",
            password="secureP@ss123",
            name="New User",
        )

        assert result.email == "[email protected]"
        assert result.name == "New User"
        mock_db.add.assert_called_once()
        mock_db.commit.assert_called_once()

    def test_raises_duplicate_email_error(self, user_service, mock_db, sample_user):
        mock_db.query.return_value.filter.return_value.first.return_value = sample_user

        with pytest.raises(DuplicateEmailError, match="already registered"):
            user_service.create_user(
                email="[email protected]",
                password="secureP@ss123",
                name="Duplicate",
            )

        mock_db.add.assert_not_called()

    def test_rolls_back_on_commit_failure(self, user_service, mock_db):
        mock_db.commit.side_effect = Exception("Connection lost")

        with pytest.raises(Exception, match="Connection lost"):
            user_service.create_user(
                email="[email protected]",
                password="secureP@ss123",
                name="Fail",
            )

        mock_db.rollback.assert_called_once()

    @pytest.mark.parametrize(
        "password,reason",
        [
            ("short", "too short"),
            ("nouppercase1!", "missing uppercase"),
            ("NOLOWERCASE1!", "missing lowercase"),
            ("NoDigits!!", "missing digit"),
            ("", "empty"),
        ],
    )
    def test_rejects_weak_passwords(self, user_service, password, reason):
        with pytest.raises(ValueError):
            user_service.create_user(
                email="[email protected]",
                password=password,
                name="Test",
            )

    def test_strips_whitespace_from_email(self, user_service, mock_db):
        result = user_service.create_user(
            email="  [email protected]  ",
            password="secureP@ss123",
            name="Spaces",
        )
        assert result.email == "[email protected]"

    def test_lowercases_email(self, user_service, mock_db):
        result = user_service.create_user(
            email="[email protected]",
            password="secureP@ss123",
            name="Upper",
        )
        assert result.email == "[email protected]"


class TestGetUser:
    """Tests for UserService.get_user method."""

    def test_returns_user_when_found(self, user_service, mock_db, sample_user):
        mock_db.query.return_value.filter.return_value.first.return_value = sample_user

        result = user_service.get_user(user_id=1)

        assert result.id == 1
        assert result.email == "[email protected]"

    def test_raises_not_found_for_missing_user(self, user_service, mock_db):
        mock_db.query.return_value.filter.return_value.first.return_value = None

        with pytest.raises(UserNotFoundError):
            user_service.get_user(user_id=999)

    def test_raises_value_error_for_invalid_id(self, user_service):
        with pytest.raises(ValueError):
            user_service.get_user(user_id=-1)

        with pytest.raises(ValueError):
            user_service.get_user(user_id=0)

pytest-specific patterns:

PatternWhen to UseExample
@pytest.fixtureShared setup for multiple testsDatabase connections, test data
@pytest.mark.parametrizeSame test with different inputsTesting validation rules, edge cases
@pytest.mark.asyncioTesting async functionsasync def test_fetch():
@pytest.mark.skip(reason="...")Temporarily skip a testBroken dependency, known issue
@pytest.mark.xfailTest expected to failDocumenting a known bug
pytest.raises(ExceptionType)Assert exception is raisedwith pytest.raises(ValueError):
pytest.approx(value)Floating point comparisonassert 0.3 == pytest.approx(0.1 + 0.2)
MagicMock / AsyncMockMock sync/async dependenciesmock = MagicMock(return_value=42)
@patch('module.function')Replace function during test@patch('app.utils.send_email')
tmp_path (built-in fixture)Temporary directory for file testsdef test_write(tmp_path):
capsys (built-in fixture)Capture stdout/stderrcaptured = capsys.readouterr()
monkeypatch (built-in fixture)Set env vars, modify objectsmonkeypatch.setenv("API_KEY", "test")
conftest.pyShare fixtures across test filesPlace in test directory root

Go -- testing package

go
package user_test

import (
    "context"
    "errors"
    "testing"
    "time"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
    "github.com/stretchr/testify/require"

    "myapp/internal/user"
)

// MockUserStore implements user.Store interface for testing
type MockUserStore struct {
    mock.Mock
}

func (m *MockUserStore) FindByEmail(ctx context.Context, email string) (*user.User, error) {
    args := m.Called(ctx, email)
    if args.Get(0) == nil {
        return nil, args.Error(1)
    }
    return args.Get(0).(*user.User), args.Error(1)
}

func (m *MockUserStore) Create(ctx context.Context, u *user.User) error {
    args := m.Called(ctx, u)
    return args.Error(0)
}

func TestCreateUser(t *testing.T) {
    t.Run("creates user with valid input", func(t *testing.T) {
        store := new(MockUserStore)
        svc := user.NewService(store)

        store.On("FindByEmail", mock.Anything, "[email protected]").Return(nil, user.ErrNotFound)
        store.On("Create", mock.Anything, mock.AnythingOfType("*user.User")).Return(nil)

        u, err := svc.Create(context.Background(), "[email protected]", "Test User")

        require.NoError(t, err)
        assert.Equal(t, "[email protected]", u.Email)
        assert.Equal(t, "Test User", u.Name)
        assert.NotEmpty(t, u.ID)
        store.AssertExpectations(t)
    })

    t.Run("returns error when email already exists", func(t *testing.T) {
        store := new(MockUserStore)
        svc := user.NewService(store)

        existing := &user.User{ID: "123", Email: "[email protected]"}
        store.On("FindByEmail", mock.Anything, "[email protected]").Return(existing, nil)

        _, err := svc.Create(context.Background(), "[email protected]", "Test")

        require.Error(t, err)
        assert.True(t, errors.Is(err, user.ErrDuplicateEmail))
        store.AssertNotCalled(t, "Create", mock.Anything, mock.Anything)
    })

    t.Run("returns error on empty email", func(t *testing.T) {
        store := new(MockUserStore)
        svc := user.NewService(store)

        _, err := svc.Create(context.Background(), "", "Test")

        require.Error(t, err)
        assert.Contains(t, err.Error(), "email is required")
    })

    t.Run("respects context cancellation", func(t *testing.T) {
        store := new(MockUserStore)
        svc := user.NewService(store)

        ctx, cancel := context.WithCancel(context.Background())
        cancel() // cancel immediately

        store.On("FindByEmail", mock.Anything, mock.Anything).Return(nil, ctx.Err())

        _, err := svc.Create(ctx, "[email protected]", "Test")

        require.Error(t, err)
        assert.True(t, errors.Is(err, context.Canceled))
    })
}

// Table-driven tests for validation
func TestValidateEmail(t *testing.T) {
    tests := []struct {
        name    string
        email   string
        wantErr bool
    }{
        {"valid email", "[email protected]", false},
        {"valid with subdomain", "[email protected]", false},
        {"valid with plus", "[email protected]", false},
        {"empty string", "", true},
        {"missing @", "userexample.com", true},
        {"missing domain", "user@", true},
        {"missing local part", "@example.com", true},
        {"double @", "user@@example.com", true},
        {"spaces in local", "us [email protected]", true},
        {"unicode domain", "user@ex\u00e4mple.com", true},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            err := user.ValidateEmail(tt.email)
            if tt.wantErr {
                assert.Error(t, err, "expected error for email: %q", tt.email)
            } else {
                assert.NoError(t, err, "unexpected error for email: %q", tt.email)
            }
        })
    }
}

Go testing patterns:

PatternWhen to UseExample
t.Run("name", func(t *testing.T){})Sub-tests for groupingOrganize tests by scenario
Table-driven testsSame logic, different inputsValidation, parsing, transformation
testify/assertNon-fatal assertionsassert.Equal(t, expected, actual)
testify/requireFatal assertions (stop test on failure)require.NoError(t, err)
testify/mockInterface mockingDefine mock structs implementing interfaces
httptest.NewServerTest HTTP handlersCreate test server with real HTTP
httptest.NewRecorderTest handler without serverRecord handler response
t.Parallel()Run sub-tests in parallelPlace at start of sub-test
t.Helper()Mark function as test helperBetter error location in output
t.Cleanup(func())Register cleanup after testClose connections, remove temp files
testing.Short()Skip slow tests with -shortif testing.Short() { t.Skip() }

Rust -- #[test] and #[cfg(test)]

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

    // Test fixtures
    fn sample_user() -> User {
        User {
            id: 1,
            email: "[email protected]".to_string(),
            name: "Test User".to_string(),
            created_at: chrono::Utc::now(),
        }
    }

    mod create_user {
        use super::*;

        #[test]
        fn creates_user_with_valid_data() {
            let repo = MockUserRepo::new();
            repo.expect_find_by_email()
                .returning(|_| Ok(None));
            repo.expect_create()
                .returning(|u| Ok(u.clone()));

            let service = UserService::new(Box::new(repo));
            let result = service.create_user("[email protected]", "secureP@ss123", "New User");

            assert!(result.is_ok());
            let user = result.unwrap();
            assert_eq!(user.email, "[email protected]");
            assert_eq!(user.name, "New User");
        }

        #[test]
        fn returns_error_for_duplicate_email() {
            let repo = MockUserRepo::new();
            repo.expect_find_by_email()
                .returning(|_| Ok(Some(sample_user())));

            let service = UserService::new(Box::new(repo));
            let result = service.create_user("[email protected]", "secureP@ss123", "Dup");

            assert!(result.is_err());
            assert!(matches!(result.unwrap_err(), UserError::DuplicateEmail(_)));
        }

        #[test]
        fn returns_error_for_empty_email() {
            let repo = MockUserRepo::new();
            let service = UserService::new(Box::new(repo));

            let result = service.create_user("", "secureP@ss123", "Test");

            assert!(result.is_err());
            assert!(matches!(result.unwrap_err(), UserError::ValidationError(_)));
        }

        #[test]
        #[should_panic(expected = "password must not be empty")]
        fn panics_on_empty_password() {
            let repo = MockUserRepo::new();
            let service = UserService::new(Box::new(repo));

            // This should panic, not return an error
            let _ = service.create_user("[email protected]", "", "Test");
        }
    }

    mod validate_email {
        use super::*;

        #[test]
        fn accepts_valid_emails() {
            let valid = vec![
                "[email protected]",
                "[email protected]",
                "[email protected]",
            ];
            for email in valid {
                assert!(validate_email(email).is_ok(), "should accept: {}", email);
            }
        }

        #[test]
        fn rejects_invalid_emails() {
            let invalid = vec![
                ("", "empty string"),
                ("@example.com", "missing local part"),
                ("user@", "missing domain"),
                ("userexample.com", "missing @"),
                ("user@@example.com", "double @"),
            ];
            for (email, reason) in invalid {
                assert!(validate_email(email).is_err(), "should reject ({}): {}", reason, email);
            }
        }
    }

    // Async test (requires tokio::test)
    mod async_operations {
        use super::*;

        #[tokio::test]
        async fn fetches_user_from_remote_api() {
            let mut mock_client = MockHttpClient::new();
            mock_client.expect_get()
                .with(eq("https://api.example.com/users/1"))
                .returning(|_| Ok(r#"{"id":1,"name":"Remote User"}"#.to_string()));

            let service = RemoteUserService::new(mock_client);
            let user = service.fetch_user(1).await.unwrap();

            assert_eq!(user.name, "Remote User");
        }

        #[tokio::test]
        async fn handles_api_timeout() {
            let mut mock_client = MockHttpClient::new();
            mock_client.expect_get()
                .returning(|_| Err(HttpError::Timeout));

            let service = RemoteUserService::new(mock_client);
            let result = service.fetch_user(1).await;

            assert!(matches!(result, Err(UserError::NetworkError(_))));
        }
    }
}

Rust testing patterns:

PatternWhen to UseExample
#[test]Mark a function as a testBasic unit test
#[cfg(test)]Compile module only during testingWrap test module
#[should_panic]Test that code panics#[should_panic(expected = "msg")]
#[ignore]Skip test unless --ignored flagSlow or integration tests
#[tokio::test]Async test with tokio runtimeAsync function testing
assert!, assert_eq!, assert_ne!Standard assertionsBuilt-in, no imports needed
matches!()Pattern matching assertionassert!(matches!(result, Ok(_)))
mockall crateGenerate mock implementations#[automock] on traits
proptest / quickcheckProperty-based testingGenerate random inputs
rstestParameterized tests (like pytest)#[rstest] with #[case]
tempfile crateTemporary files and directoriestempfile::tempdir()

Integration Test Patterns

Integration tests verify that multiple components work together correctly. They sit between unit tests (isolated) and end-to-end tests (full system).

What to Integration Test

BoundaryWhat to Verify
HTTP APIRequest parsing, routing, response format, status codes, headers
DatabaseSchema compatibility, query correctness, transaction behavior, migrations
File systemRead/write operations, path handling, permissions
External APIsRequest format, response parsing, error handling, retry behavior
Message queuesPublish/consume, message format, ordering, dead letter handling
Cache layerCache hit/miss, invalidation, serialization, TTL

Integration Test Structure

text
1. Setup -- Create real or in-memory dependencies (test database, temp files)
2. Seed -- Insert test data into the dependency
3. Execute -- Call the code under test
4. Assert -- Verify the result AND the side effects on the dependency
5. Cleanup -- Tear down test data (or let the framework handle it)

HTTP API Integration Test (Jest + Supertest)

javascript
import request from 'supertest';
import { app } from '../src/app';
import { db } from '../src/database';

describe('POST /api/users', () => {
  beforeAll(async () => {
    await db.migrate.latest();
  });

  afterEach(async () => {
    await db('users').truncate();
  });

  afterAll(async () => {
    await db.destroy();
  });

  it('returns 201 and creates user in database', async () => {
    const response = await request(app)
      .post('/api/users')
      .send({ email: '[email protected]', password: 'Secure123!', name: 'Test' })
      .expect(201);

    expect(response.body.user.email).toBe('[email protected]');
    expect(response.body.user).not.toHaveProperty('password');

    // Verify side effect: user exists in database
    const dbUser = await db('users').where({ email: '[email protected]' }).first();
    expect(dbUser).toBeDefined();
    expect(dbUser.name).toBe('Test');
  });

  it('returns 409 when email already exists', async () => {
    // Seed
    await db('users').insert({ email: '[email protected]', password: 'hash', name: 'Existing' });

    const response = await request(app)
      .post('/api/users')
      .send({ email: '[email protected]', password: 'Secure123!', name: 'Dup' })
      .expect(409);

    expect(response.body.error).toContain('already registered');
  });

  it('returns 400 with validation errors for missing fields', async () => {
    const response = await request(app)
      .post('/api/users')
      .send({})
      .expect(400);

    expect(response.body.errors).toEqual(
      expect.arrayContaining([
        expect.objectContaining({ field: 'email' }),
        expect.objectContaining({ field: 'password' }),
      ])
    );
  });

  it('returns 415 for non-JSON content type', async () => {
    await request(app)
      .post('/api/users')
      .set('Content-Type', 'text/plain')
      .send('not json')
      .expect(415);
  });
});

Database Integration Test (pytest + SQLAlchemy)

python
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from app.models import Base, User
from app.repositories.user_repo import UserRepository


@pytest.fixture(scope="module")
def engine():
    """Create an in-memory SQLite engine for testing."""
    engine = create_engine("sqlite:///:memory:")
    Base.metadata.create_all(engine)
    yield engine
    engine.dispose()


@pytest.fixture
def session(engine):
    """Create a new database session for each test."""
    Session = sessionmaker(bind=engine)
    session = Session()
    yield session
    session.rollback()
    session.close()


@pytest.fixture
def repo(session):
    return UserRepository(session)


class TestUserRepository:
    def test_create_and_find(self, repo, session):
        user = repo.create(email="[email protected]", name="Test")
        session.flush()

        found = repo.find_by_email("[email protected]")
        assert found is not None
        assert found.name == "Test"
        assert found.id == user.id

    def test_find_returns_none_for_missing(self, repo):
        assert repo.find_by_email("[email protected]") is None

    def test_unique_constraint_on_email(self, repo, session):
        repo.create(email="[email protected]", name="First")
        session.flush()

        with pytest.raises(Exception):  # IntegrityError
            repo.create(email="[email protected]", name="Second")
            session.flush()


Coverage-Driven Test Prioritization

Not all code deserves equal testing effort. Prioritize based on risk.

Risk Assessment Matrix

FactorLow RiskMedium RiskHigh Risk
Data handlingRead-only, displayTransform, filterCreate, update, delete
User inputNo user inputValidated inputRaw user input
MoneyNo financial impactReporting/displayTransactions, billing
External depsNoneRead from externalWrite to external
FrequencyRarely calledPeriodicEvery request
Blast radiusSingle userTeam/organizationAll users
Test budget allocation:
  • High risk code: 90%+ coverage, including edge cases and error paths
  • Medium risk code: 70%+ coverage, happy path + main error cases
  • Low risk code: 50%+ coverage, happy path only
  • Generated/boilerplate code: 0% (don't test framework code)

What NOT to Test

Do not waste time testing:

  • Framework internals (React rendering, Express routing, Django ORM)
  • Third-party library behavior (axios, lodash, numpy)
  • Simple getters/setters with no logic
  • Configuration files
  • Type definitions or interfaces
  • Constants and enums (unless derived from computation)
  • CSS/styling (use visual regression tools instead)
  • Code that is trivially correct by inspection

Snapshot Testing Guidance

Snapshots are useful for detecting unintended changes in structured output. They are NOT a substitute for behavioral assertions.

Good uses for snapshots:

  • API response shape verification (JSON structure, not values)
  • React component rendered output (JSX structure)
  • Error message format consistency
  • CLI help text output
  • Generated SQL queries
  • Serialized configuration
Bad uses for snapshots (avoid):
  • Testing computed values (use expect(value).toBe(expected))
  • Testing timestamps or random IDs (snapshots will always fail)
  • Testing large objects where most properties are irrelevant
  • As a substitute for understanding what the code should produce
Snapshot hygiene:
  • Review every snapshot update in code review. Don't blindly --update.
  • Use toMatchInlineSnapshot() for small outputs so the expected value lives in the test.
  • Use .toMatchSnapshot() for large outputs, but name them: .toMatchSnapshot('user creation response').
  • If a snapshot file has more than 50 entries, your tests are probably too coupled to output format.

Performance Test Patterns

Performance tests verify that code meets speed and resource requirements.

Timing Tests

javascript
// Jest
it('processes 10,000 records in under 500ms', () => {
  const records = Array.from({ length: 10_000 }, (_, i) => ({ id: i, value: `item-${i}` }));

  const start = performance.now();
  const result = processRecords(records);
  const elapsed = performance.now() - start;

  expect(result).toHaveLength(10_000);
  expect(elapsed).toBeLessThan(500);
});

python
# pytest
import time

def test_bulk_insert_performance(repo, session):
    """Bulk insert should handle 1000 records in under 2 seconds."""
    users = [{"email": f"user{i}@example.com", "name": f"User {i}"} for i in range(1000)]

    start = time.monotonic()
    repo.bulk_create(users)
    session.flush()
    elapsed = time.monotonic() - start

    assert elapsed < 2.0, f"Bulk insert took {elapsed:.2f}s, expected < 2.0s"

go
// Go
func BenchmarkProcessRecords(b *testing.B) {
    records := make([]Record, 10_000)
    for i := range records {
        records[i] = Record{ID: i, Value: fmt.Sprintf("item-%d", i)}
    }

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        ProcessRecords(records)
    }
}

Memory Usage Tests

go
func TestMemoryUsage(t *testing.T) {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    before := m.Alloc

    // Run the operation
    result := ProcessLargeDataset(generateTestData(100_000))

    runtime.ReadMemStats(&m)
    after := m.Alloc

    // Should not allocate more than 50MB for 100K records
    allocatedMB := float64(after-before) / 1024 / 1024
    assert.Less(t, allocatedMB, 50.0, "allocated %.2f MB, expected < 50 MB", allocatedMB)
    _ = result
}


Output Format

When generating tests, always produce complete, runnable test files. Include:

  • All necessary imports -- framework, mocks, module under test
  • Test fixtures -- reusable setup data and helper functions
  • Organized test groups -- one describe/class per function or feature
  • Clear test names -- following the naming conventions above
  • Specific assertions -- not just toBeTruthy() or assert result
  • Edge case coverage -- at minimum: empty input, boundary values, error paths
  • Comments only where the intent is non-obvious -- tests should be self-documenting via names
File naming conventions:

FrameworkTest File PatternLocation
Jest.test.ts, .spec.ts__tests__/ or next to source
Vitest.test.ts, .spec.ts__tests__/ or next to source
pytesttest_.py, _test.pytests/ directory
Go*_test.goSame package as source
Rustmod tests blockSame file as source

Complete Workflow

When a user gives you code to test, follow this exact process:

  • Read the code -- understand what it does, its public API, its dependencies
  • Identify the framework -- detect or ask: Jest, Vitest, pytest, Go, Rust
  • Run the strategy analysis -- public surface, complexity, coupling, mock plan
  • Generate the test file -- complete, runnable, with all imports and setup
  • Prioritize coverage -- test high-risk paths first, skip trivial code
  • List edge cases explicitly -- call out which edge cases you tested and which you skipped (and why)
  • Suggest additional tests -- recommend integration tests, performance tests, or property-based tests if appropriate
If the code is too large to test in one file, split into logical test files and explain the structure.

If the code has no tests at all, start with the highest-risk function and work outward. Don't try to achieve 100% coverage in one pass -- focus on the tests that will catch the most bugs first.


"The purpose of testing is not to prove the code works. It's to find the places where it doesn't." -- Taylor (Sovereign AI)

Installation

Terminal bash

openclaw install sovereign-test-generator
    
Copied!

💻Code Examples

it('calls bcrypt.hash') // testing implementation, not behavior

itcalls-bcrypthash--testing-implementation-not-behavior.txt
**Naming rules:**
- Start with a verb: creates, returns, throws, emits, sends, rejects, resolves
- Describe the condition: "when email is missing", "with invalid token", "after timeout"
- State the expected outcome: "returns 404", "throws ValidationError", "emits 'disconnect' event"
- Full pattern: `it('<verb> <outcome> when <condition>')`

### Assertion Best Practices

**Be specific in assertions:**

expect(error.code).toBe('VALIDATION_ERROR');

expecterrorcodetobevalidationerror.txt
**Assert the right things:**

| What to Assert | Why |
|----------------|-----|
| Return values | Verify the function produces correct output |
| Error types and messages | Verify failures are meaningful and catchable |
| Side effects (via mocks) | Verify the function interacts correctly with dependencies |
| State changes | Verify mutations happened correctly |
| Call counts | Verify functions are called the right number of times (no duplicate calls) |
| Call order | Verify sequential operations happen in the right order |
| Thrown exceptions | Verify error handling paths work |
| Async resolution/rejection | Verify promises settle correctly |

**One logical assertion per test.** Multiple `expect` calls are fine if they test the same logical behavior (e.g., checking multiple properties of a return object). But don't test two unrelated behaviors in one test.

---

## Edge Case Identification

For every function, systematically check these categories:

### Input Boundaries

| Category | Test Cases |
|----------|------------|
| **Empty/Missing** | `null`, `undefined`, `""`, `[]`, `{}`, `0`, `NaN`, `false` |
| **Boundary Values** | Min value, max value, min-1, max+1, exactly at boundary |
| **Type Coercion** | String where number expected, number where string expected, boolean as number |
| **Special Characters** | Unicode, emoji, newlines, tabs, null bytes, very long strings (10K+ chars) |
| **Numeric Edge Cases** | `0`, `-0`, `Infinity`, `-Infinity`, `NaN`, `Number.MAX_SAFE_INTEGER`, `Number.MIN_SAFE_INTEGER`, floating point precision (`0.1 + 0.2`) |
| **Collection Edge Cases** | Empty array, single element, duplicate elements, very large collections (10K+ items) |
| **Date/Time** | Midnight, DST transitions, leap years (Feb 29), Unix epoch, year 2038, timezone boundaries |
| **Concurrency** | Simultaneous calls, out-of-order responses, timeout during operation |

### Error Paths

| Category | Test Cases |
|----------|------------|
| **Network Failures** | Connection timeout, DNS resolution failure, 500 response, malformed JSON response |
| **Database Failures** | Connection lost mid-query, constraint violation, deadlock, table doesn't exist |
| **File System** | File not found, permission denied, disk full, path too long, concurrent writes |
| **Authentication** | Expired token, malformed token, missing token, revoked token, wrong algorithm |
| **Authorization** | Insufficient permissions, role escalation attempt, accessing other user's data |
| **Rate Limiting** | Exceeding rate limit, retry-after behavior, burst vs sustained rate |
| **Resource Exhaustion** | Out of memory (simulate with large inputs), too many open connections, stack overflow |

### Business Logic Edge Cases

These are domain-specific and require understanding the code's purpose:

- **E-commerce:** Zero-quantity order, negative price, coupon applied twice, out-of-stock during checkout
- **User management:** Duplicate registration, self-deletion, admin demoting themselves
- **Financial:** Rounding errors, currency conversion, overdraft, concurrent balance updates
- **Search:** Empty query, SQL injection attempt, very long query, special regex characters
- **Pagination:** Page 0, page -1, page beyond total, changing page size mid-session

---

## Framework-Specific Patterns

### JavaScript / TypeScript -- Jest

});

.txt
**Jest-specific patterns:**

| Pattern | When to Use | Example |
|---------|-------------|---------|
| `jest.fn()` | Create a standalone mock function | `const callback = jest.fn()` |
| `jest.mock('module')` | Auto-mock an entire module | Top of file, before imports |
| `jest.spyOn(obj, 'method')` | Spy on existing method without replacing | `jest.spyOn(console, 'error')` |
| `jest.useFakeTimers()` | Control `setTimeout`, `setInterval`, `Date.now` | Testing debounce, polling, expiration |
| `jest.advanceTimersByTime(ms)` | Fast-forward fake timers | `jest.advanceTimersByTime(5000)` |
| `expect.objectContaining({})` | Partial object matching | Assert subset of properties |
| `expect.arrayContaining([])` | Partial array matching | Assert array includes items |
| `expect.any(Constructor)` | Type matching | `expect.any(Number)` |
| `.mockResolvedValue(val)` | Mock async function return | `mock.mockResolvedValue({id: 1})` |
| `.mockRejectedValue(err)` | Mock async function throw | `mock.mockRejectedValue(new Error())` |
| `toMatchInlineSnapshot()` | Inline snapshot for small outputs | Verify exact structure in test file |

### JavaScript / TypeScript -- Vitest

});

.txt
**Vitest-specific notes:**
- Use `vi.fn()` instead of `jest.fn()`
- Use `vi.mock()` instead of `jest.mock()`
- Use `vi.spyOn()` instead of `jest.spyOn()`
- Use `vi.useFakeTimers()` and `vi.advanceTimersByTime()`
- Vitest supports ESM natively -- no need for `--experimental-vm-modules`
- Use `vi.hoisted()` for imports that need to be available during `vi.mock()` factory

### Python -- pytest

user_service.get_user(user_id=0)

-userservicegetuseruserid0.txt
**pytest-specific patterns:**

| Pattern | When to Use | Example |
|---------|-------------|---------|
| `@pytest.fixture` | Shared setup for multiple tests | Database connections, test data |
| `@pytest.mark.parametrize` | Same test with different inputs | Testing validation rules, edge cases |
| `@pytest.mark.asyncio` | Testing async functions | `async def test_fetch():` |
| `@pytest.mark.skip(reason="...")` | Temporarily skip a test | Broken dependency, known issue |
| `@pytest.mark.xfail` | Test expected to fail | Documenting a known bug |
| `pytest.raises(ExceptionType)` | Assert exception is raised | `with pytest.raises(ValueError):` |
| `pytest.approx(value)` | Floating point comparison | `assert 0.3 == pytest.approx(0.1 + 0.2)` |
| `MagicMock` / `AsyncMock` | Mock sync/async dependencies | `mock = MagicMock(return_value=42)` |
| `@patch('module.function')` | Replace function during test | `@patch('app.utils.send_email')` |
| `tmp_path` (built-in fixture) | Temporary directory for file tests | `def test_write(tmp_path):` |
| `capsys` (built-in fixture) | Capture stdout/stderr | `captured = capsys.readouterr()` |
| `monkeypatch` (built-in fixture) | Set env vars, modify objects | `monkeypatch.setenv("API_KEY", "test")` |
| `conftest.py` | Share fixtures across test files | Place in test directory root |

### Go -- testing package

}

.txt
**Go testing patterns:**

| Pattern | When to Use | Example |
|---------|-------------|---------|
| `t.Run("name", func(t *testing.T){})` | Sub-tests for grouping | Organize tests by scenario |
| Table-driven tests | Same logic, different inputs | Validation, parsing, transformation |
| `testify/assert` | Non-fatal assertions | `assert.Equal(t, expected, actual)` |
| `testify/require` | Fatal assertions (stop test on failure) | `require.NoError(t, err)` |
| `testify/mock` | Interface mocking | Define mock structs implementing interfaces |
| `httptest.NewServer` | Test HTTP handlers | Create test server with real HTTP |
| `httptest.NewRecorder` | Test handler without server | Record handler response |
| `t.Parallel()` | Run sub-tests in parallel | Place at start of sub-test |
| `t.Helper()` | Mark function as test helper | Better error location in output |
| `t.Cleanup(func())` | Register cleanup after test | Close connections, remove temp files |
| `testing.Short()` | Skip slow tests with `-short` | `if testing.Short() { t.Skip() }` |

### Rust -- #[test] and #[cfg(test)]

}

.txt
**Rust testing patterns:**

| Pattern | When to Use | Example |
|---------|-------------|---------|
| `#[test]` | Mark a function as a test | Basic unit test |
| `#[cfg(test)]` | Compile module only during testing | Wrap test module |
| `#[should_panic]` | Test that code panics | `#[should_panic(expected = "msg")]` |
| `#[ignore]` | Skip test unless `--ignored` flag | Slow or integration tests |
| `#[tokio::test]` | Async test with tokio runtime | Async function testing |
| `assert!`, `assert_eq!`, `assert_ne!` | Standard assertions | Built-in, no imports needed |
| `matches!()` | Pattern matching assertion | `assert!(matches!(result, Ok(_)))` |
| `mockall` crate | Generate mock implementations | `#[automock]` on traits |
| `proptest` / `quickcheck` | Property-based testing | Generate random inputs |
| `rstest` | Parameterized tests (like pytest) | `#[rstest]` with `#[case]` |
| `tempfile` crate | Temporary files and directories | `tempfile::tempdir()` |

---

## Integration Test Patterns

Integration tests verify that multiple components work together correctly. They sit between unit tests (isolated) and end-to-end tests (full system).

### What to Integration Test

| Boundary | What to Verify |
|----------|---------------|
| **HTTP API** | Request parsing, routing, response format, status codes, headers |
| **Database** | Schema compatibility, query correctness, transaction behavior, migrations |
| **File system** | Read/write operations, path handling, permissions |
| **External APIs** | Request format, response parsing, error handling, retry behavior |
| **Message queues** | Publish/consume, message format, ordering, dead letter handling |
| **Cache layer** | Cache hit/miss, invalidation, serialization, TTL |

### Integration Test Structure

session.flush()

-sessionflush.txt
---

## Coverage-Driven Test Prioritization

Not all code deserves equal testing effort. Prioritize based on risk.

### Risk Assessment Matrix

| Factor | Low Risk | Medium Risk | High Risk |
|--------|----------|-------------|-----------|
| **Data handling** | Read-only, display | Transform, filter | Create, update, delete |
| **User input** | No user input | Validated input | Raw user input |
| **Money** | No financial impact | Reporting/display | Transactions, billing |
| **External deps** | None | Read from external | Write to external |
| **Frequency** | Rarely called | Periodic | Every request |
| **Blast radius** | Single user | Team/organization | All users |

**Test budget allocation:**
- High risk code: 90%+ coverage, including edge cases and error paths
- Medium risk code: 70%+ coverage, happy path + main error cases
- Low risk code: 50%+ coverage, happy path only
- Generated/boilerplate code: 0% (don't test framework code)

### What NOT to Test

Do not waste time testing:
- Framework internals (React rendering, Express routing, Django ORM)
- Third-party library behavior (axios, lodash, numpy)
- Simple getters/setters with no logic
- Configuration files
- Type definitions or interfaces
- Constants and enums (unless derived from computation)
- CSS/styling (use visual regression tools instead)
- Code that is trivially correct by inspection

---

## Snapshot Testing Guidance

Snapshots are useful for detecting unintended changes in structured output. They are NOT a substitute for behavioral assertions.

**Good uses for snapshots:**
- API response shape verification (JSON structure, not values)
- React component rendered output (JSX structure)
- Error message format consistency
- CLI help text output
- Generated SQL queries
- Serialized configuration

**Bad uses for snapshots (avoid):**
- Testing computed values (use `expect(value).toBe(expected)`)
- Testing timestamps or random IDs (snapshots will always fail)
- Testing large objects where most properties are irrelevant
- As a substitute for understanding what the code should produce

**Snapshot hygiene:**
- Review every snapshot update in code review. Don't blindly `--update`.
- Use `toMatchInlineSnapshot()` for small outputs so the expected value lives in the test.
- Use `.toMatchSnapshot()` for large outputs, but name them: `.toMatchSnapshot('user creation response')`.
- If a snapshot file has more than 50 entries, your tests are probably too coupled to output format.

---

## Performance Test Patterns

Performance tests verify that code meets speed and resource requirements.

### Timing Tests
example.txt
describe('UserService.createUser')
  it('creates a user with valid email and password')
  it('returns validation error when email is missing')
  it('returns validation error when password is shorter than 8 characters')
  it('hashes the password before storing')
  it('returns conflict error when email already exists')
  it('sends welcome email after successful creation')
  it('rolls back database insert if email sending fails')
example.txt
it('test1')
it('should work')
it('handles error')
it('createUser test')
it('calls bcrypt.hash')  // testing implementation, not behavior

Tags

#web_and-frontend-development #code

Quick Info

Category Development
Model Claude 3.5
Complexity One-Click
Author ryudi84
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install sovereign-test-generator