TestNG offers two parameterization mechanisms: @Parameters (values injected from testng.xml, good for a few environment values) and @DataProvider (a method returning many data sets, for true data-driven testing).
@Parameters("browser") with a matching <parameter name='browser' value='chrome'/> in testng.xml injects a single configured value — ideal for environment/config (browser, URL). @DataProvider is a method returning Object[][] (or an Iterator) where each row runs the linked @Test once — ideal for many input/expected combinations (valid/invalid logins, boundary values). A @Test references it via @Test(dataProvider = 'creds'). DataProviders can be shared (in a separate class), parallelized (parallel = true), and receive Method/ITestContext for context. Use @Parameters for suite-level config, @DataProvider for iterating a test over data.
@DataProvider supplies ten (username, password, expected) rows to one login @Test, so all credential permutations run from a single method and each case reports separately.
When would you use @Parameters versus @DataProvider in TestNG?