Token导航 LogoToken导航

Agent Skill · 待分类

testng-data-driven(测试数据驱动)

用于辅助数据整理、表格处理、CSV/Excel 分析、指标计算和图表准备。它适合让 Agent 清洗字段、汇总数据、发现异常、生成统计口径或把分析结果转成可读说明。使用时需要确认数据来源、字段含义和时间范围,避免把样本数据当全量事实;涉及敏感数据、导出文件或批量写回时,应先确认权限和脱敏边界。

testng-data-driven 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为操作浏览器;许可证为 MIT,第三方扫描已通过,按安装量在待分类类的 11,209 个 Skill 里排第 5,188。

总安装 605周安装 26GitHub Stars 142下载 212核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

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

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

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

用于辅助数据整理、表格处理和 CSV/Excel 分析。适合清洗字段、汇总数据、发现异常或生成统计口径。使用时需确认数据来源、字段含义和时间范围。testng-data-driven 属于待分类类 Skill,可作为该场景下的辅助能力补充。涉及敏感数据或批量写回时应先确认权限和脱敏边界。

安装方式:github,支持 Codex、Claude、Cursor、Gemini CLI。

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

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

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

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

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

常见问题

6 条

testng-data-driven 怎么安装?

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

testng-data-driven 支持哪些 AI 工具?

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

testng-data-driven 需要什么权限?

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

testng-data-driven 是免费的吗?

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

testng-data-driven 用的人多吗?

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

testng-data-driven 安全吗?

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

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

值得选的地方

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

先想清楚的地方

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

适不适合你

更适合

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

不太适合

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

待分类类 Skill 对比

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

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
testng-data-driven

测试数据驱动 · 本页

605142操作浏览器MIT通过

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

SKILL.md 原文

TestNG Data-Driven Testing

Master TestNG data-driven testing including DataProviders, Factory patterns, and parameterization for comprehensive test coverage. This skill covers techniques for testing with multiple data sets efficiently.

Overview

Data-driven testing separates test logic from test data, enabling a single test method to run against multiple inputs. TestNG provides powerful features for data-driven testing through DataProviders, Factory methods, and XML parameterization.

DataProvider Basics

Simple DataProvider

import org.testng.annotations.*;
import static org.testng.Assert.*;

public class SimpleDataProviderTest {

    @DataProvider(name = "numbers")
    public Object[][] provideNumbers() {
        return new Object[][] {
            {1, 2, 3},
            {4, 5, 9},
            {0, 0, 0},
            {-1, 1, 0}
        };
    }

    @Test(dataProvider = "numbers")
    public void testAddition(int a, int b, int expected) {
        assertEquals(a + b, expected);
    }
}

DataProvider with Single Values

public class SingleValueDataProviderTest {

    @DataProvider(name = "validEmails")
    public Object[][] provideValidEmails() {
        return new Object[][] {
            {"user@example.com"},
            {"test.user@domain.org"},
            {"admin+tag@company.co.uk"},
            {"user123@test.io"}
        };
    }

    @Test(dataProvider = "validEmails")
    public void testValidEmail(String email) {
        assertTrue(isValidEmail(email), "Email should be valid: " + email);
    }

    private boolean isValidEmail(String email) {
        return email != null && email.matches("^[\\w+.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$");
    }
}

Advanced DataProvider Patterns

DataProvider in Separate Class

// DataProviders class
public class TestDataProviders {

    @DataProvider(name = "userData")
    public static Object[][] provideUserData() {
        return new Object[][] {
            {"john", "john@example.com", 25},
            {"jane", "jane@example.com", 30},
            {"bob", "bob@example.com", 22}
        };
    }

    @DataProvider(name = "loginCredentials")
    public static Object[][] provideLoginCredentials() {
        return new Object[][] {
            {"admin", "admin123", true},
            {"user", "user456", true},
            {"invalid", "wrong", false}
        };
    }
}

// Test class using external DataProvider
public class UserTest {

    @Test(dataProvider = "userData", dataProviderClass = TestDataProviders.class)
    public void testUserCreation(String name, String email, int age) {
        User user = new User(name, email, age);
        assertNotNull(user);
        assertEquals(user.getName(), name);
        assertEquals(user.getEmail(), email);
        assertEquals(user.getAge(), age);
    }

    @Test(dataProvider = "loginCredentials", dataProviderClass = TestDataProviders.class)
    public void testLogin(String username, String password, boolean expectedSuccess) {
        boolean result = authService.login(username, password);
        assertEquals(result, expectedSuccess);
    }
}

DataProvider with Method Context

import org.testng.ITestContext;
import org.testng.annotations.*;
import java.lang.reflect.Method;

public class ContextAwareDataProviderTest {

    @DataProvider(name = "contextAwareData")
    public Object[][] provideContextAwareData(ITestContext context, Method method) {
        String testName = method.getName();
        String suiteName = context.getSuite().getName();

        System.out.println("Providing data for: " + testName + " in suite: " + suiteName);

        if (testName.contains("Admin")) {
            return new Object[][] {
                {"admin", "ADMIN_ROLE"},
                {"superadmin", "SUPER_ADMIN_ROLE"}
            };
        } else {
            return new Object[][] {
                {"user1", "USER_ROLE"},
                {"user2", "USER_ROLE"}
            };
        }
    }

    @Test(dataProvider = "contextAwareData")
    public void testAdminAccess(String username, String role) {
        // Test admin access
    }

    @Test(dataProvider = "contextAwareData")
    public void testUserAccess(String username, String role) {
        // Test user access
    }
}

Parallel DataProvider

public class ParallelDataProviderTest {

    @DataProvider(name = "parallelData", parallel = true)
    public Object[][] provideParallelData() {
        return new Object[][] {
            {"Test 1"},
            {"Test 2"},
            {"Test 3"},
            {"Test 4"},
            {"Test 5"},
            {"Test 6"},
            {"Test 7"},
            {"Test 8"},
            {"Test 9"},
            {"Test 10"}
        };
    }

    @Test(dataProvider = "parallelData")
    public void testParallel(String data) {
        System.out.println(Thread.currentThread().getName() + " - " + data);
        // Tests run in parallel threads
    }
}

Iterator DataProvider

import java.util.Iterator;
import java.util.Arrays;

public class IteratorDataProviderTest {

    @DataProvider(name = "iteratorData")
    public Iterator<Object[]> provideIteratorData() {
        // Useful for large datasets - generates data on demand
        return Arrays.asList(
            new Object[]{"data1", 1},
            new Object[]{"data2", 2},
            new Object[]{"data3", 3}
        ).iterator();
    }

    @Test(dataProvider = "iteratorData")
    public void testWithIterator(String name, int value) {
        assertNotNull(name);
        assertTrue(value > 0);
    }
}

Lazy DataProvider for Large Datasets

import java.util.Iterator;
import java.util.NoSuchElementException;

public class LazyDataProviderTest {

    @DataProvider(name = "lazyData")
    public Iterator<Object[]> provideLazyData() {
        return new Iterator<Object[]>() {
            private int current = 0;
            private final int max = 1000;

            @Override
            public boolean hasNext() {
                return current < max;
            }

            @Override
            public Object[] next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                // Generate data on demand
                return new Object[]{
                    "User_" + current,
                    "user" + current + "@example.com",
                    current++
                };
            }
        };
    }

    @Test(dataProvider = "lazyData")
    public void testLargeDataset(String name, String email, int id) {
        assertNotNull(name);
        assertTrue(email.contains("@"));
    }
}

Factory Pattern

Basic Factory

import org.testng.annotations.*;

public class FactoryTest {
    private String browser;

    @Factory
    public static Object[] createInstances() {
        return new Object[] {
            new FactoryTest("chrome"),
            new FactoryTest("firefox"),
            new FactoryTest("safari")
        };
    }

    public FactoryTest(String browser) {
        this.browser = browser;
    }

    @Test
    public void testHomePage() {
        System.out.println("Testing home page on: " + browser);
    }

    @Test
    public void testLoginPage() {
        System.out.println("Testing login page on: " + browser);
    }
}

Factory with DataProvider

public class FactoryWithDataProviderTest {
    private String username;
    private String role;

    @Factory(dataProvider = "userRoles")
    public FactoryWithDataProviderTest(String username, String role) {
        this.username = username;
        this.role = role;
    }

    @DataProvider(name = "userRoles")
    public static Object[][] provideUserRoles() {
        return new Object[][] {
            {"admin", "ADMIN"},
            {"manager", "MANAGER"},
            {"user", "USER"},
            {"guest", "GUEST"}
        };
    }

    @Test
    public void testUserPermissions() {
        System.out.println("Testing permissions for " + username + " with role " + role);
        // Test specific permissions based on role
    }

    @Test
    public void testUserDashboard() {
        System.out.println("Testing dashboard for " + username + " with role " + role);
        // Test dashboard features based on role
    }

    @Override
    public String toString() {
        return username + "_" + role;
    }
}

External Data Sources

CSV DataProvider

import java.io.*;
import java.util.*;

public class CsvDataProviderTest {

    @DataProvider(name = "csvData")
    public Object[][] provideCsvData() throws IOException {
        List<Object[]> data = new ArrayList<>();

        try (BufferedReader reader = new BufferedReader(
                new FileReader("src/test/resources/testdata.csv"))) {

            String line;
            // Skip header
            reader.readLine();

            while ((line = reader.readLine()) != null) {
                String[] values = line.split(",");
                data.add(new Object[]{
                    values[0].trim(),  // username
                    values[1].trim(),  // email
                    Integer.parseInt(values[2].trim())  // age
                });
            }
        }

        return data.toArray(new Object[0][]);
    }

    @Test(dataProvider = "csvData")
    public void testUserFromCsv(String username, String email, int age) {
        assertNotNull(username);
        assertTrue(email.contains("@"));
        assertTrue(age > 0);
    }
}

JSON DataProvider

import com.fasterxml.jackson.databind.*;
import java.io.*;
import java.util.*;

public class JsonDataProviderTest {

    @DataProvider(name = "jsonData")
    public Object[][] provideJsonData() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        List<Map<String, Object>> testData = mapper.readValue(
            new File("src/test/resources/testdata.json"),
            new TypeReference<List<Map<String, Object>>>() {}
        );

        Object[][] data = new Object[testData.size()][3];
        for (int i = 0; i < testData.size(); i++) {
            Map<String, Object> entry = testData.get(i);
            data[i][0] = entry.get("name");
            data[i][1] = entry.get("email");
            data[i][2] = ((Number) entry.get("age")).intValue();
        }

        return data;
    }

    @Test(dataProvider = "jsonData")
    public void testUserFromJson(String name, String email, int age) {
        assertNotNull(name);
        assertFalse(name.isEmpty());
    }
}

Excel DataProvider

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.util.*;

public class ExcelDataProviderTest {

    @DataProvider(name = "excelData")
    public Object[][] provideExcelData() throws IOException {
        List<Object[]> data = new ArrayList<>();

        try (FileInputStream fis = new FileInputStream("src/test/resources/testdata.xlsx");
             Workbook workbook = new XSSFWorkbook(fis)) {

            Sheet sheet = workbook.getSheetAt(0);

            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row != null) {
                    data.add(new Object[]{
                        getCellValue(row.getCell(0)),
                        getCellValue(row.getCell(1)),
                        (int) row.getCell(2).getNumericCellValue()
                    });
                }
            }
        }

        return data.toArray(new Object[0][]);
    }

    private String getCellValue(Cell cell) {
        if (cell == null) return "";
        return cell.getCellType() == CellType.STRING
            ? cell.getStringCellValue()
            : String.valueOf((int) cell.getNumericCellValue());
    }

    @Test(dataProvider = "excelData")
    public void testUserFromExcel(String name, String email, int age) {
        assertNotNull(name);
        assertTrue(age >= 0);
    }
}

Advanced Parameterization

Optional Parameters

public class OptionalParameterTest {

    @Parameters({"browser", "timeout"})
    @BeforeClass
    public void setUp(
            String browser,
            @Optional("30000") String timeout) {

        System.out.println("Browser: " + browser);
        System.out.println("Timeout: " + timeout);
    }

    @Test
    public void testMethod() {
        // Test implementation
    }
}

Combining Parameters and DataProviders

public class CombinedParametersTest {

    private String environment;

    @Parameters("environment")
    @BeforeClass
    public void setUp(String environment) {
        this.environment = environment;
    }

    @DataProvider(name = "users")
    public Object[][] provideUsers() {
        return new Object[][] {
            {"user1", "pass1"},
            {"user2", "pass2"}
        };
    }

    @Test(dataProvider = "users")
    public void testLogin(String username, String password) {
        System.out.println("Testing on " + environment + " with user: " + username);
        // Combine XML parameter with DataProvider data
    }
}

Dynamic DataProvider Based on Parameters

public class DynamicDataProviderTest {

    private static String environment;

    @Parameters("environment")
    @BeforeClass
    public static void setUp(@Optional("staging") String env) {
        environment = env;
    }

    @DataProvider(name = "environmentData")
    public Object[][] provideEnvironmentData() {
        switch (environment) {
            case "production":
                return new Object[][] {
                    {"prod-user1", "prod-api-key-1"},
                    {"prod-user2", "prod-api-key-2"}
                };
            case "staging":
                return new Object[][] {
                    {"staging-user1", "staging-api-key-1"},
                    {"staging-user2", "staging-api-key-2"}
                };
            default:
                return new Object[][] {
                    {"dev-user", "dev-api-key"}
                };
        }
    }

    @Test(dataProvider = "environmentData")
    public void testApiAccess(String user, String apiKey) {
        System.out.println("Testing API access for: " + user + " on " + environment);
    }
}

Data Provider Naming

Named Data Provider Rows

public class NamedDataProviderTest {

    @DataProvider(name = "testCases")
    public Object[][] provideTestCases() {
        return new Object[][] {
            // Each row can have a name for better reporting
            {"TC001_ValidLogin", "admin", "admin123", true},
            {"TC002_InvalidPassword", "admin", "wrong", false},
            {"TC003_EmptyUsername", "", "password", false},
            {"TC004_SpecialCharacters", "user@#$", "pass@#$", false}
        };
    }

    @Test(dataProvider = "testCases")
    public void testLogin(String testCaseId, String username, String password, boolean expected) {
        System.out.println("Executing: " + testCaseId);
        // Test implementation
    }
}

Best Practices

  1. Keep DataProviders focused - One DataProvider per data type or scenario
  2. Use external files for large datasets - CSV, JSON, or Excel for maintainability
  3. Make DataProviders static when shared - Required for external DataProvider classes
  4. Include test case identifiers - First column can be test case ID for tracing
  5. Use meaningful DataProvider names - Clear names improve test reports
  6. Consider parallel execution - Enable parallel flag for independent tests
  7. Handle null values explicitly - Define behavior for null/empty data
  8. Document expected formats - Comment data structure for complex providers
  9. Use Iterator for large datasets - Avoid memory issues with lazy loading
  10. Separate test data from test logic - Keep tests clean and data manageable

Common Pitfalls

  1. Type mismatches - DataProvider types must match test method parameters
  2. Missing static modifier - External DataProvider methods must be static
  3. Array dimension errors - Must return Object[][] not Object[]
  4. Null pointer exceptions - Not handling null values in data
  5. Resource leaks - Not closing file streams in DataProviders
  6. Tight coupling - Hard-coding environment-specific data
  7. Over-parameterization - Too many parameters make tests hard to read
  8. Missing test case IDs - Hard to trace failures without identifiers
  9. Ignoring execution order - DataProvider rows may run in any order
  10. Not considering parallelism - Shared state issues with parallel DataProviders

When to Use This Skill

  • Testing with multiple input combinations
  • Implementing boundary value testing
  • Creating cross-browser or cross-environment tests
  • Loading test data from external sources
  • Building parameterized test suites
  • Creating data-driven API tests
  • Implementing database-driven tests
  • Building reusable test data frameworks

平台分布

Claude Code

29.53%
按下载量换算63

Codex

21.25%
按下载量换算45

OpenCode

18.26%
按下载量换算39

trae

11.12%
按下载量换算24

Antigravity

6.77%
按下载量换算14

windsurf

3.42%
按下载量换算7

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

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

安装前确认

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

继续浏览同类 Skills