Token导航 LogoToken导航

Agent Skill · 运维和基础设施

testng-parallel(并行测试)

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

testng-parallel 是运维和基础设施类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为操作浏览器;许可证为 MIT,第三方扫描已通过,按安装量在运维和基础设施类的 2,449 个 Skill 里排第 1,547。

总安装 499周安装 20GitHub Stars 142下载 162核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:testng-parallel(并行测试)
来源仓库:https://github.com/thebushidocollective/han
仓库路径:skills/testng-parallel
安装命令:
npx skills add https://github.com/thebushidocollective/han --skill testng-parallel
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/thebushidocollective/han --skill testng-parallel

这个 Skill 是做什么的

运维和基础设施类 Skill 处理部署、监控、日志和云资源,多数需要较高的执行权限。

用于辅助测试设计、自动化测试、用例整理和回归验证。适合编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需确认项目测试框架、运行命令和夹具数据,避免误改真实逻辑。涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。建议结合原始 README 进一步核验具体用法和限制条件。

来源仓库内路径:skills/testng-parallel

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thebushidocollective/han --skill testng-parall…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要操作浏览器,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

testng-parallel 怎么安装?

在终端执行 npx skills add https://github.com/thebushidocollective/han --skill testng-parallel。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

testng-parallel 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

testng-parallel 需要什么权限?

权限级别是操作浏览器。该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

testng-parallel 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

testng-parallel 用的人多吗?

公开数据是累计安装 499 次,近一周安装 20 次,下载 162 次,GitHub 142 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

testng-parallel 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理运维和基础设施类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

运维和基础设施类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
brainstorming

头脑风暴 · Codex、Claude

3,148,776173,131操作浏览器MIT通过
copywriting

文案写作 · Codex、Claude

1,996,72425,583需要联网MIT通过
openclaw-secure-linux-cloud

OpenClaw secure linux cloud 命令行 · Codex、Claude

1,853,08840接触敏感数据未明确未通过
xget

xget 命令行 · Codex、Claude

1,799,28040执行命令未明确未通过
requesting-code-review

代码审查请求 · Codex、Claude

1,590,144173,103权限未标注MIT通过
testng-parallel

并行测试 · 本页

499142操作浏览器MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

TestNG Parallel Execution

Master TestNG parallel test execution including thread pool configuration, suite-level parallelism, method-level parallelism, and thread safety patterns. This skill covers techniques for maximizing test throughput while maintaining test reliability.

Overview

TestNG supports parallel execution at multiple levels: suite, test, class, and method. Proper parallel configuration can significantly reduce test execution time, but requires careful consideration of thread safety and resource management.

Parallel Execution Modes

Suite-Level Parallelism

Run multiple <test> tags in parallel:

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Parallel Suite" parallel="tests" thread-count="3">

    <test name="Chrome Tests">
        <classes>
            <class name="com.example.tests.BrowserTest"/>
        </classes>
    </test>

    <test name="Firefox Tests">
        <classes>
            <class name="com.example.tests.BrowserTest"/>
        </classes>
    </test>

    <test name="Safari Tests">
        <classes>
            <class name="com.example.tests.BrowserTest"/>
        </classes>
    </test>

</suite>

Class-Level Parallelism

Run test classes in parallel:

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Parallel Classes" parallel="classes" thread-count="4">

    <test name="All Tests">
        <classes>
            <class name="com.example.tests.UserServiceTest"/>
            <class name="com.example.tests.ProductServiceTest"/>
            <class name="com.example.tests.OrderServiceTest"/>
            <class name="com.example.tests.PaymentServiceTest"/>
        </classes>
    </test>

</suite>

Method-Level Parallelism

Run test methods in parallel:

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Parallel Methods" parallel="methods" thread-count="5">

    <test name="Service Tests">
        <classes>
            <class name="com.example.tests.IndependentMethodsTest"/>
        </classes>
    </test>

</suite>

Instance-Level Parallelism

Run test instances in parallel (useful with Factory):

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Parallel Instances" parallel="instances" thread-count="3">

    <test name="Factory Tests">
        <classes>
            <class name="com.example.tests.FactoryGeneratedTest"/>
        </classes>
    </test>

</suite>

Thread Pool Configuration

Basic Thread Configuration

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Thread Pool Suite" parallel="methods" thread-count="10">
    <!-- Global thread pool configuration -->

    <test name="Test Group 1" thread-count="5">
        <!-- Override for this specific test -->
        <classes>
            <class name="com.example.tests.Test1"/>
        </classes>
    </test>

    <test name="Test Group 2">
        <!-- Uses suite-level thread-count -->
        <classes>
            <class name="com.example.tests.Test2"/>
        </classes>
    </test>

</suite>

Data Provider Parallel Execution

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="DataProvider Suite" data-provider-thread-count="20">

    <test name="Data Driven Tests">
        <classes>
            <class name="com.example.tests.ParallelDataProviderTest"/>
        </classes>
    </test>

</suite>
public class ParallelDataProviderTest {

    @DataProvider(name = "largeDataSet", parallel = true)
    public Object[][] provideLargeDataSet() {
        Object[][] data = new Object[100][2];
        for (int i = 0; i < 100; i++) {
            data[i] = new Object[]{"User" + i, "user" + i + "@example.com"};
        }
        return data;
    }

    @Test(dataProvider = "largeDataSet")
    public void testWithParallelData(String name, String email) {
        System.out.println(Thread.currentThread().getName() + " - Testing: " + name);
        // Each data row runs in parallel
    }
}

Thread Safety Patterns

Thread-Local Storage

import org.testng.annotations.*;

public class ThreadLocalTest {

    // Thread-local storage for test-specific resources
    private static ThreadLocal<WebDriver> driverThread = new ThreadLocal<>();
    private static ThreadLocal<String> sessionThread = new ThreadLocal<>();

    @BeforeMethod
    public void setUp() {
        // Initialize thread-local resources
        driverThread.set(createWebDriver());
        sessionThread.set(generateSessionId());
    }

    @AfterMethod
    public void tearDown() {
        // Clean up thread-local resources
        WebDriver driver = driverThread.get();
        if (driver != null) {
            driver.quit();
        }
        driverThread.remove();
        sessionThread.remove();
    }

    @Test
    public void testParallelBrowser() {
        WebDriver driver = driverThread.get();
        String session = sessionThread.get();
        System.out.println("Thread: " + Thread.currentThread().getName() +
                          " Session: " + session);
        // Use thread-local driver
    }

    private WebDriver createWebDriver() {
        // Create browser instance
        return new ChromeDriver();
    }

    private String generateSessionId() {
        return UUID.randomUUID().toString();
    }
}

Synchronized Shared Resources

import org.testng.annotations.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ConcurrentHashMap;

public class SynchronizedResourceTest {

    // Thread-safe counter
    private static AtomicInteger testCounter = new AtomicInteger(0);

    // Thread-safe collection
    private static ConcurrentHashMap<String, String> sharedCache = new ConcurrentHashMap<>();

    // Lock object for critical sections
    private static final Object lock = new Object();

    @Test(threadPoolSize = 5, invocationCount = 100)
    public void testAtomicOperations() {
        int count = testCounter.incrementAndGet();
        System.out.println("Test count: " + count);
    }

    @Test(threadPoolSize = 3, invocationCount = 50)
    public void testConcurrentMap() {
        String threadName = Thread.currentThread().getName();
        sharedCache.put(threadName, String.valueOf(System.currentTimeMillis()));
        // Thread-safe without explicit synchronization
    }

    @Test(threadPoolSize = 2, invocationCount = 10)
    public void testSynchronizedBlock() {
        synchronized (lock) {
            // Critical section - only one thread at a time
            performCriticalOperation();
        }
    }

    private void performCriticalOperation() {
        // Operations that require exclusive access
    }
}

Immutable Test Data

import java.util.Collections;
import java.util.List;
import java.util.Arrays;

public class ImmutableDataTest {

    // Immutable test data - inherently thread-safe
    private static final List<String> TEST_USERS = Collections.unmodifiableList(
        Arrays.asList("user1", "user2", "user3", "user4", "user5")
    );

    private static final Map<String, String> CONFIG = Collections.unmodifiableMap(
        Map.of(
            "url", "https://api.example.com",
            "timeout", "30000",
            "retries", "3"
        )
    );

    @Test(threadPoolSize = 5, invocationCount = 20)
    public void testWithImmutableData() {
        // Safe to read from multiple threads
        int userIndex = ThreadLocalRandom.current().nextInt(TEST_USERS.size());
        String user = TEST_USERS.get(userIndex);
        String url = CONFIG.get("url");

        System.out.println(Thread.currentThread().getName() +
                          " - User: " + user + ", URL: " + url);
    }
}

Test Isolation Patterns

Independent Test Methods

public class IndependentTestsExample {

    // Each test method is completely independent
    @Test
    public void testFeatureA() {
        // Create its own resources
        UserService service = new UserService();
        User user = service.createUser("testA");
        assertNotNull(user);
        // Clean up
        service.deleteUser(user.getId());
    }

    @Test
    public void testFeatureB() {
        // Completely separate from testFeatureA
        ProductService service = new ProductService();
        Product product = service.createProduct("testB");
        assertNotNull(product);
        service.deleteProduct(product.getId());
    }

    @Test
    public void testFeatureC() {
        // No shared state with other tests
        OrderService service = new OrderService();
        Order order = service.createOrder();
        assertNotNull(order);
        service.cancelOrder(order.getId());
    }
}

Isolated Database Tests

import org.testng.annotations.*;

public class IsolatedDatabaseTest {

    private Connection connection;
    private String testSchema;

    @BeforeMethod
    public void setUp() throws SQLException {
        // Create isolated schema for each test
        testSchema = "test_" + Thread.currentThread().getId() + "_" + System.currentTimeMillis();
        connection = DriverManager.getConnection(DB_URL, USER, PASSWORD);
        connection.createStatement().execute("CREATE SCHEMA " + testSchema);
        connection.setCatalog(testSchema);
        initializeTestData();
    }

    @AfterMethod
    public void tearDown() throws SQLException {
        // Drop isolated schema
        connection.createStatement().execute("DROP SCHEMA " + testSchema + " CASCADE");
        connection.close();
    }

    @Test
    public void testDatabaseOperation1() throws SQLException {
        // Operations in isolated schema
        PreparedStatement ps = connection.prepareStatement(
            "INSERT INTO users (name) VALUES (?)"
        );
        ps.setString(1, "TestUser1");
        ps.executeUpdate();

        ResultSet rs = connection.createStatement().executeQuery(
            "SELECT COUNT(*) FROM users"
        );
        rs.next();
        assertEquals(rs.getInt(1), 1);
    }

    @Test
    public void testDatabaseOperation2() throws SQLException {
        // Completely isolated from testDatabaseOperation1
        PreparedStatement ps = connection.prepareStatement(
            "INSERT INTO products (name) VALUES (?)"
        );
        ps.setString(1, "TestProduct");
        ps.executeUpdate();
    }

    private void initializeTestData() throws SQLException {
        // Create tables in isolated schema
    }
}

Parallel Execution with Dependencies

Preserving Order Within Groups

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Ordered Parallel" parallel="classes" thread-count="3">

    <test name="Ordered Test" preserve-order="true">
        <classes>
            <!-- Classes run in parallel, methods in order -->
            <class name="com.example.tests.OrderedTest1">
                <methods>
                    <include name="step1"/>
                    <include name="step2"/>
                    <include name="step3"/>
                </methods>
            </class>
            <class name="com.example.tests.OrderedTest2"/>
        </classes>
    </test>

</suite>

Group Threading

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Group Threading" parallel="methods" thread-count="4" group-by-instances="true">

    <test name="Instance Grouped">
        <classes>
            <class name="com.example.tests.InstanceGroupTest"/>
        </classes>
    </test>

</suite>
public class InstanceGroupTest {

    private String instanceId;

    @Factory
    public Object[] createInstances() {
        return new Object[] {
            new InstanceGroupTest("instance1"),
            new InstanceGroupTest("instance2"),
            new InstanceGroupTest("instance3")
        };
    }

    public InstanceGroupTest() {}

    public InstanceGroupTest(String instanceId) {
        this.instanceId = instanceId;
    }

    @Test
    public void step1() {
        System.out.println(instanceId + " - Step 1");
    }

    @Test(dependsOnMethods = "step1")
    public void step2() {
        System.out.println(instanceId + " - Step 2");
    }

    @Test(dependsOnMethods = "step2")
    public void step3() {
        System.out.println(instanceId + " - Step 3");
    }
}

Performance Optimization

Optimal Thread Count

public class ThreadCountOptimization {

    // Determine optimal thread count based on available resources
    public static int getOptimalThreadCount() {
        int availableProcessors = Runtime.getRuntime().availableProcessors();

        // For CPU-bound tests
        int cpuBoundThreads = availableProcessors;

        // For I/O-bound tests (network, file, database)
        int ioBoundThreads = availableProcessors * 2;

        // For mixed workloads
        int mixedThreads = (int) (availableProcessors * 1.5);

        return mixedThreads;
    }
}

Resource Pool Pattern

import java.util.concurrent.*;

public class ResourcePoolTest {

    // Connection pool for parallel tests
    private static BlockingQueue<Connection> connectionPool;

    @BeforeSuite
    public void setUpSuite() {
        int poolSize = 10;
        connectionPool = new ArrayBlockingQueue<>(poolSize);
        for (int i = 0; i < poolSize; i++) {
            connectionPool.offer(createConnection());
        }
    }

    @AfterSuite
    public void tearDownSuite() {
        Connection conn;
        while ((conn = connectionPool.poll()) != null) {
            closeConnection(conn);
        }
    }

    @Test(threadPoolSize = 5, invocationCount = 50)
    public void testWithPooledConnection() throws InterruptedException {
        Connection conn = connectionPool.take(); // Borrow
        try {
            // Use connection
            performDatabaseOperation(conn);
        } finally {
            connectionPool.offer(conn); // Return
        }
    }

    private Connection createConnection() {
        // Create database connection
        return null;
    }

    private void closeConnection(Connection conn) {
        // Close connection
    }

    private void performDatabaseOperation(Connection conn) {
        // Database operations
    }
}

Reporting for Parallel Tests

Custom Reporter for Parallel Execution

import org.testng.*;
import java.util.concurrent.ConcurrentHashMap;

public class ParallelTestReporter implements ITestListener {

    private static ConcurrentHashMap<Long, List<String>> threadTestMap =
        new ConcurrentHashMap<>();

    @Override
    public void onTestStart(ITestResult result) {
        long threadId = Thread.currentThread().getId();
        threadTestMap.computeIfAbsent(threadId, k -> new CopyOnWriteArrayList<>())
                     .add(result.getName());
    }

    @Override
    public void onFinish(ITestContext context) {
        System.out.println("\n=== Thread Distribution Report ===");
        threadTestMap.forEach((threadId, tests) -> {
            System.out.println("Thread " + threadId + ": " + tests.size() + " tests");
            tests.forEach(test -> System.out.println("  - " + test));
        });
        System.out.println("Total threads used: " + threadTestMap.size());
    }
}

Timeout Configuration

public class TimeoutTest {

    @Test(timeOut = 5000)
    public void testWithTimeout() {
        // Fails if takes more than 5 seconds
    }

    @Test(timeOut = 10000, threadPoolSize = 3, invocationCount = 10)
    public void testParallelWithTimeout() {
        // Each invocation has 10 second timeout
    }
}
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Timeout Suite" time-out="60000">
    <!-- Suite-level timeout: 60 seconds total -->

    <test name="Quick Tests" time-out="10000">
        <!-- Test-level timeout: 10 seconds for all tests in this group -->
        <classes>
            <class name="com.example.tests.QuickTest"/>
        </classes>
    </test>

</suite>

Best Practices

  1. Design for independence - Tests should not depend on shared mutable state
  2. Use ThreadLocal for per-thread resources - Drivers, sessions, connections
  3. Prefer immutable data - Thread-safe by design
  4. Set appropriate thread counts - Based on resource availability
  5. Implement proper cleanup - Prevent resource leaks in parallel execution
  6. Use thread-safe collections - ConcurrentHashMap, CopyOnWriteArrayList
  7. Configure timeouts - Prevent hung tests from blocking threads
  8. Monitor thread distribution - Ensure balanced workload
  9. Test locally first - Verify thread safety before CI/CD
  10. Document thread safety requirements - Clear expectations for test authors

Common Pitfalls

  1. Shared mutable state - Causes race conditions and flaky tests
  2. Static fields without synchronization - Not thread-safe
  3. Resource contention - Too many threads competing for limited resources
  4. Order dependencies - Tests that assume execution order
  5. Missing cleanup - ThreadLocal resources not removed
  6. Insufficient isolation - Database tests affecting each other
  7. Too many threads - Overhead exceeds benefits
  8. Ignoring timeouts - Hung tests blocking execution
  9. Non-deterministic failures - Hard to reproduce parallel issues
  10. Improper connection pooling - Connection leaks or exhaustion

When to Use This Skill

  • Reducing test suite execution time
  • Configuring CI/CD parallel test execution
  • Implementing thread-safe test infrastructure
  • Designing parallel-friendly test architecture
  • Troubleshooting parallel test failures
  • Optimizing resource utilization in tests
  • Building scalable test frameworks
  • Implementing cross-browser parallel testing

平台分布

OpenCode

27.27%
按下载量换算44

Codex

20.05%
按下载量换算32

Claude Code

18.43%
按下载量换算30

windsurf

12.1%
按下载量换算20

trae

8.11%
按下载量换算13

Antigravity

3.68%
按下载量换算6

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills