Skip to content

Commit

Permalink
Added: DataProvider can now take an ITestContext parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeust committed Dec 28, 2006
1 parent e58af1d commit 10efd59
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 43 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
@@ -1,6 +1,7 @@
===========================================================================
5.5

Added: DataProvider can now take an ITestContext parameter
Fixed: Wasn't parsing <selector-class-name> correctly
Fixed: Annotation Transformers now work on class-level annotations
Fixed: Some class-level @Test attributes were not always honored
Expand Down
6 changes: 4 additions & 2 deletions src/main/org/testng/TestRunner.java
Expand Up @@ -593,7 +593,8 @@ public void privateRun(XmlTest xmlTest) {
afterClassMethods,
m_allTestMethods,
m_groupMethods,
cmm));
cmm,
this));
}
}

Expand All @@ -612,7 +613,8 @@ public void privateRun(XmlTest xmlTest) {
afterClassMethods,
m_allTestMethods,
m_groupMethods,
cmm));
cmm,
this));
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/org/testng/internal/IInvoker.java
Expand Up @@ -4,6 +4,7 @@
import java.util.Map;

import org.testng.IClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.xml.XmlSuite;
Expand Down Expand Up @@ -49,5 +50,6 @@ public List<ITestResult> invokeTestMethods(ITestNGMethod testMethod,
XmlSuite suite,
Map<String, String> parameters,
ConfigurationGroupMethods groupMethods,
Object[] instances);
Object[] instances,
ITestContext testContext);
}
15 changes: 10 additions & 5 deletions src/main/org/testng/internal/Invoker.java
Expand Up @@ -625,7 +625,8 @@ public List<ITestResult> invokeTestMethods(ITestNGMethod testMethod,
XmlSuite suite,
Map<String, String> parameters,
ConfigurationGroupMethods groupMethods,
Object[] instances)
Object[] instances,
ITestContext testContext)
{
// Potential bug here if the test method was declared on a parent class
assert null != testMethod.getTestClass()
Expand Down Expand Up @@ -663,7 +664,8 @@ public List<ITestResult> invokeTestMethods(ITestNGMethod testMethod,
//
if (testMethod.getThreadPoolSize() > 1) {
try {
result= invokePooledTestMethods(testMethod, allTestMethods, suite, parameters, groupMethods);
result = invokePooledTestMethods(testMethod, allTestMethods, suite,
parameters, groupMethods, testContext);
}
finally {
failureCount = handleInvocationResults(testMethod, result, failureCount, expectedExceptionClasses, false);
Expand All @@ -681,7 +683,7 @@ public List<ITestResult> invokeTestMethods(ITestNGMethod testMethod,
Map<String, String> allParameterNames = new HashMap<String, String>();
Iterator<Object[]> allParameterValues =
Parameters.handleParameters(testMethod, allParameterNames,
testClass, parameters, suite, m_annotationFinder);
testClass, parameters, suite, m_annotationFinder, testContext);

while (allParameterValues.hasNext()) {
Object[] parameterValues= allParameterValues.next();
Expand Down Expand Up @@ -742,7 +744,9 @@ private List<ITestResult> invokePooledTestMethods(ITestNGMethod testMethod,
ITestNGMethod[] allTestMethods,
XmlSuite suite,
Map<String, String> parameters,
ConfigurationGroupMethods groupMethods) {
ConfigurationGroupMethods groupMethods,
ITestContext testContext)
{
// HINT: invoke @BeforeGroups on the original method (reduce thread contention, and also solve thread confinement)
ITestClass testClass= testMethod.getTestClass();
Object[] instances = testClass.getInstances(true);
Expand All @@ -768,7 +772,8 @@ private List<ITestResult> invokePooledTestMethods(ITestNGMethod testMethod,
mi,
suite,
parameters,
allTestMethods));
allTestMethods,
testContext));
}

try {
Expand Down
39 changes: 27 additions & 12 deletions src/main/org/testng/internal/MethodHelper.java
Expand Up @@ -14,6 +14,7 @@

import org.testng.IHookCallBack;
import org.testng.ITestClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.TestNGException;
Expand Down Expand Up @@ -642,27 +643,41 @@ public static Iterator<Object[]> createArrayIterator(final Object[][] objects) {
}

public static Iterator<Object[]> invokeDataProvider(Object instance,
Method dataProvider, ITestNGMethod method)
Method dataProvider, ITestNGMethod method, ITestContext testContext)
{
Iterator<Object[]> result = null;
Method testMethod = method.getMethod();

// If it returns an Object[][], convert it to an Iterable<Object[]>
try {
Object[] parameters = null;

// If the DataProvider accepts a Method as first parameter, pass the
// current test method
List<Object> lParameters = new ArrayList<Object>();

// Go through all the parameters declared on this Data Provider and
// make sure we have at most one Method and one ITestContext.
// Anything else is an error
Class[] parameterTypes = dataProvider.getParameterTypes();
if (parameterTypes.length > 0 && parameterTypes[0].equals(Method.class)) {
parameters = new Object[] {
testMethod
};
if (parameterTypes.length > 2) {
throw new TestNGException("DataProvider " + dataProvider + " cannot have more than two parameters");
}
else if (parameterTypes.length > 0) {
throw new TestNGException("DataProvider " + dataProvider + " needs to have "
+ " either zero parameters or one parameter of type java.lang.reflect.Method");

for (Class cls : parameterTypes) {
if (cls.equals(Method.class)) {
lParameters.add(testMethod);
}
else if (cls.equals(ITestContext.class)) {
lParameters.add(testContext);
}
}
Object[] parameters = lParameters.toArray(new Object[lParameters.size()]);
// if (parameterTypes.length > 0 && parameterTypes[0].equals(Method.class)) {
// parameters = new Object[] {
// testMethod
// };
// }
// else if (parameterTypes.length > 0) {
// throw new TestNGException("DataProvider " + dataProvider + " needs to have "
// + " either zero parameters or one parameter of type java.lang.reflect.Method");
// }

Class< ? > returnType = dataProvider.getReturnType();
if (Object[][].class.isAssignableFrom(returnType)) {
Expand Down
7 changes: 5 additions & 2 deletions src/main/org/testng/internal/Parameters.java
Expand Up @@ -9,6 +9,7 @@
import java.util.Map;

import org.testng.ITestClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.TestNGException;
import org.testng.internal.annotations.AnnotationHelper;
Expand Down Expand Up @@ -321,7 +322,8 @@ public static Iterator<Object[]> handleParameters(ITestNGMethod testMethod,
ITestClass testClass,
Map<String, String> parameters,
XmlSuite xmlSuite,
IAnnotationFinder annotationFinder)
IAnnotationFinder annotationFinder,
ITestContext testContext)
{
Iterator<Object[]> result = null;

Expand All @@ -346,7 +348,8 @@ public static Iterator<Object[]> handleParameters(ITestNGMethod testMethod,
result = MethodHelper.invokeDataProvider(
instance, /* a test instance or null if the dataprovider is static*/
dataProvider,
testMethod);
testMethod,
testContext);
}
else {
//
Expand Down
22 changes: 15 additions & 7 deletions src/main/org/testng/internal/TestMethodWorker.java
Expand Up @@ -4,10 +4,10 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.testng.ClassMethodMap;
import org.testng.ITestClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.internal.thread.ThreadUtil;
Expand Down Expand Up @@ -38,6 +38,7 @@ public class TestMethodWorker implements IMethodWorker {
protected List<ITestResult> m_testResults = new ArrayList<ITestResult>();
protected ConfigurationGroupMethods m_groupMethods = null;
protected ClassMethodMap m_classMethodMap = null;
private ITestContext m_testContext = null;

public TestMethodWorker(IInvoker invoker,
MethodInstance[] testMethods,
Expand All @@ -47,7 +48,8 @@ public TestMethodWorker(IInvoker invoker,
Map<ITestClass, ITestClass> invokedAfterClassMethods,
ITestNGMethod[] allTestMethods,
ConfigurationGroupMethods groupMethods,
ClassMethodMap classMethodMap)
ClassMethodMap classMethodMap,
ITestContext testContext)
{
m_invoker = invoker;
m_testMethods = testMethods;
Expand All @@ -58,6 +60,7 @@ public TestMethodWorker(IInvoker invoker,
m_allTestMethods = allTestMethods;
m_groupMethods = groupMethods;
m_classMethodMap = classMethodMap;
m_testContext = testContext;
}

/**
Expand Down Expand Up @@ -103,15 +106,17 @@ public void run() {
// Invoke test method
//
try {
invokeTestMethods(tm, m_testMethods[indexMethod].getInstances());
invokeTestMethods(tm, m_testMethods[indexMethod].getInstances(), m_testContext);
}
finally {
invokeAfterClassMethods(testClass, tm);
}
}
}

protected void invokeTestMethods(ITestNGMethod tm, Object[] instances) {
protected void invokeTestMethods(ITestNGMethod tm, Object[] instances,
ITestContext testContext)
{
// Potential bug here: we look up the method index of tm among all
// the test methods (not very efficient) but if this method appears
// several times and these methods are run in parallel, the results
Expand All @@ -123,7 +128,8 @@ protected void invokeTestMethods(ITestNGMethod tm, Object[] instances) {
m_suite,
m_parameters,
m_groupMethods,
instances);
instances,
testContext);

if (testResults != null) {
m_testResults.addAll(testResults);
Expand Down Expand Up @@ -239,7 +245,8 @@ public SingleTestMethodWorker(IInvoker invoker,
MethodInstance testMethod,
XmlSuite suite,
Map<String, String> parameters,
ITestNGMethod[] allTestMethods)
ITestNGMethod[] allTestMethods,
ITestContext testContext)
{
super(invoker,
new MethodInstance[] {testMethod},
Expand All @@ -249,7 +256,8 @@ public SingleTestMethodWorker(IInvoker invoker,
null,
allTestMethods,
EMPTY_GROUP_METHODS,
null);
null,
testContext);
}

protected void invokeAfterClassMethods(ITestClass testClass, ITestNGMethod tm) {
Expand Down
50 changes: 50 additions & 0 deletions test/src/test/dataprovider/TestContextSampleTest.java
@@ -0,0 +1,50 @@
package test.dataprovider;

import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

/**
* Tests that when a DataProvider is declared with an ITestContext,
* this parameter is correctly passed.
*
* Created on Dec 28, 2006
* @author <a href="mailto:cedric@beust.com">Cedric Beust</a>
*/
public class TestContextSampleTest {

/**
* @return As many parameters as the name of the included group
*/
@DataProvider(name = "testContext")
public Object[][] createContext(ITestContext ctx) {
// ppp("CONTEXT:" + ctx);
String[] groups = ctx.getIncludedGroups();

int n = groups.length > 0 ? new Integer(groups[0]): 0;
Object[] result = new Object[n];
for (int i = 0; i < n; i++) {
result[i] = "foo";
}

return new Object[][] {
new Object[] { result },
};
}

private static void ppp(String s) {
System.out.println("[TestContextSampleTest] " + s);
}

@Test(dataProvider = "testContext", groups="10")
public void verifyTen(Object[] objects) {
Assert.assertEquals(objects.length, 10);
}

@Test(dataProvider = "testContext", groups="5")
public void verifyFive(Object[] objects) {
Assert.assertEquals(objects.length, 5);
}

}
46 changes: 46 additions & 0 deletions test/src/test/dataprovider/TestContextTest.java
@@ -0,0 +1,46 @@
package test.dataprovider;

import org.testng.Assert;
import org.testng.TestListenerAdapter;
import org.testng.TestNG;
import org.testng.annotations.Test;

public class TestContextTest {

@Test
public void verifyTen() {
verify("10", "verifyTen", 1, 0);
}

@Test
public void verifyFive() {
verify("5", "verifyFive", 1, 0);
}

@Test
public void verifySix() {
// Not including any group, so the two test methods should fail
verify(null, null, 0, 2);
}

private void verify(String groupName, String passed, int passedCount, int failedCount) {
TestNG tng = new TestNG();
tng.setVerbose(0);
tng.setTestClasses(new Class[] { TestContextSampleTest.class });
if (groupName != null) {
tng.setGroups(groupName);
}
TestListenerAdapter al = new TestListenerAdapter();
tng.addListener(al);
tng.run();

if (passedCount > 0) {
Assert.assertEquals(al.getPassedTests().size(), passedCount);
Assert.assertEquals(al.getPassedTests().get(0).getMethod().getMethodName(), passed);
}

if (failedCount > 0) {
Assert.assertEquals(al.getFailedTests().size(), failedCount);
}
}
}

0 comments on commit 10efd59

Please sign in to comment.