Skip to content

Commit

Permalink
test execution context is handed through from engine to test methods
Browse files Browse the repository at this point in the history
  • Loading branch information
jlink committed Nov 14, 2015
1 parent 936d997 commit c82f479
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 64 deletions.
Expand Up @@ -12,7 +12,6 @@


import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Stack;


import lombok.Value; import lombok.Value;


Expand All @@ -25,6 +24,4 @@ public class ExecutionRequest {


private Map<String, Object> attributes = new HashMap<>(); private Map<String, Object> attributes = new HashMap<>();


private Stack<Object> testInstances = new Stack<>();

} }
Expand Up @@ -60,24 +60,18 @@ public void execute(ExecutionRequest request, TestExecutionContext context) {
} }


Object testInstance = createTestInstance(); Object testInstance = createTestInstance();
request.getTestInstances().push(testInstance);


try { try {
executeBeforeAllMethods(testClass, testInstance); executeBeforeAllMethods(testClass, testInstance);
for (TestExecutionNode child : getChildren()) { for (TestExecutionNode child : getChildren()) {
executeChild(child, request, context); executeChild(child, request, context, testInstance);
} }
} }
catch (Exception e) { catch (Exception e) {
request.getTestExecutionListener().testFailed(getTestDescriptor(), e); request.getTestExecutionListener().testFailed(getTestDescriptor(), e);
} }
finally { finally {
try { executeAfterAllMethods(request, testClass, testInstance);
executeAfterAllMethods(request, testClass, testInstance);
}
finally {
request.getTestInstances().pop();
}
} }
} }


Expand Down
Expand Up @@ -35,13 +35,17 @@ public EngineDescriptor getTestDescriptor() {
@Override @Override
public void execute(ExecutionRequest request, TestExecutionContext context) { public void execute(ExecutionRequest request, TestExecutionContext context) {
for (TestExecutionNode child : getChildren()) { for (TestExecutionNode child : getChildren()) {
executeChild(child, request, context); executeChild(child, request, context, null);
} }
} }


public void executeRequest(ExecutionRequest request) { public void executeRequest(ExecutionRequest request) {
TestExecutionContext context = createChildContext(getTestDescriptor(), null); TestExecutionContext context = createTopLevelContext();
execute(request, context); execute(request, context);
} }


private TestExecutionContext createTopLevelContext() {
return createContext(getTestDescriptor(), null, null, null, null);
}

} }
Expand Up @@ -14,9 +14,6 @@


import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;


import org.junit.gen5.api.After; import org.junit.gen5.api.After;
import org.junit.gen5.api.Before; import org.junit.gen5.api.Before;
Expand Down Expand Up @@ -68,13 +65,13 @@ public void execute(ExecutionRequest request, TestExecutionContext context) {
} }


request.getTestExecutionListener().testStarted(getTestDescriptor()); request.getTestExecutionListener().testStarted(getTestDescriptor());
Object testInstance = request.getTestInstances().peek(); Object testInstance = context.getTestInstance().get();
Class<?> testClass = testInstance.getClass(); Class<?> testClass = testInstance.getClass();
Throwable exceptionThrown = null; Throwable exceptionThrown = null;


try { try {
executeBeforeMethods(request, testClass, testInstance); executeBeforeMethods(context);
invokeTestMethod(request, testInstance); invokeTestMethod(context.getTestMethod().get(), context);
} }
catch (Throwable ex) { catch (Throwable ex) {
exceptionThrown = ex; exceptionThrown = ex;
Expand All @@ -83,7 +80,7 @@ public void execute(ExecutionRequest request, TestExecutionContext context) {
} }
} }
finally { finally {
exceptionThrown = executeAfterMethods(request, testClass, testInstance, exceptionThrown); exceptionThrown = executeAfterMethods(context, exceptionThrown);
} }


if (exceptionThrown != null) { if (exceptionThrown != null) {
Expand All @@ -102,61 +99,35 @@ else if (exceptionThrown instanceof TestAbortedException) {
} }
} }


private void invokeMethod(ExecutionRequest request, Method method, Object target) { private void invokeMethod(Method method, TestExecutionContext context) {
MethodArgumentResolverRegistry resolverRegistry = buildMethodArgumentResolverRegistry(); MethodArgumentResolverRegistry resolverRegistry = buildMethodArgumentResolverRegistry();
populateRegistryForMethod(resolverRegistry, method); populateRegistryForMethod(resolverRegistry, context.getTestMethod().get());


MethodInvoker methodInvoker = new MethodInvoker(method, target, resolverRegistry.getResolvers()); MethodInvoker methodInvoker = new MethodInvoker(method, context.getTestInstance().get(),
resolverRegistry.getResolvers());


// TODO Introduce factory for TestExecutionContext instances. // TODO Introduce factory for TestExecutionContext instances.
// TODO Cache & reuse TestExecutionContext instance so extensions can share state. // TODO Cache & reuse TestExecutionContext instance so extensions can share state.
methodInvoker.invoke(new TestExecutionContext() { methodInvoker.invoke(context);

private final Map<String, Object> attributes = new HashMap<>();

@Override
public Optional<Class<?>> getTestClass() {
return Optional.of(getTestDescriptor().getTestMethod().getDeclaringClass());
}

@Override
public Optional<Method> getTestMethod() {
return Optional.of(getTestDescriptor().getTestMethod());
}

@Override
public Optional<Object> getTestInstance() {
return Optional.of(target);
}

@Override
public String getDisplayName() {
return getTestDescriptor().getDisplayName();
}

@Override
public Map<String, Object> getAttributes() {
return this.attributes;
}
});
} }


private void invokeTestMethod(ExecutionRequest context, Object testInstance) { private void invokeTestMethod(Method method, TestExecutionContext context) {
invokeMethod(context, getTestDescriptor().getTestMethod(), testInstance); invokeMethod(method, context);
} }


private void executeBeforeMethods(ExecutionRequest context, Class<?> testClass, Object testInstance) { private void executeBeforeMethods(TestExecutionContext context) {
for (Method method : findAnnotatedMethods(testClass, Before.class, MethodSortOrder.HierarchyDown)) { for (Method method : findAnnotatedMethods(context.getTestClass().get(), Before.class,
invokeMethod(context, method, testInstance); MethodSortOrder.HierarchyDown)) {
invokeMethod(method, context);
} }
} }


private Throwable executeAfterMethods(ExecutionRequest context, Class<?> testClass, Object testInstance, private Throwable executeAfterMethods(TestExecutionContext context, Throwable exceptionThrown) {
Throwable exceptionThrown) {


for (Method method : findAnnotatedMethods(testClass, After.class, MethodSortOrder.HierarchyUp)) { for (Method method : findAnnotatedMethods(context.getTestClass().get(), After.class,
MethodSortOrder.HierarchyUp)) {
try { try {
invokeMethod(context, method, testInstance); invokeMethod(method, context);
} }
catch (Throwable ex) { catch (Throwable ex) {
Throwable currentException = ex; Throwable currentException = ex;
Expand Down
Expand Up @@ -10,6 +10,7 @@


package org.junit.gen5.engine.junit5.execution; package org.junit.gen5.engine.junit5.execution;


import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
Expand All @@ -20,6 +21,8 @@
import org.junit.gen5.api.extension.TestExecutionContext; import org.junit.gen5.api.extension.TestExecutionContext;
import org.junit.gen5.engine.ExecutionRequest; import org.junit.gen5.engine.ExecutionRequest;
import org.junit.gen5.engine.TestDescriptor; import org.junit.gen5.engine.TestDescriptor;
import org.junit.gen5.engine.junit5.descriptor.ClassTestDescriptor;
import org.junit.gen5.engine.junit5.descriptor.MethodTestDescriptor;


/** /**
* @author Stefan Bechtold * @author Stefan Bechtold
Expand Down Expand Up @@ -49,12 +52,35 @@ public final List<TestExecutionNode> getChildren() {


public abstract void execute(ExecutionRequest request, TestExecutionContext context); public abstract void execute(ExecutionRequest request, TestExecutionContext context);


protected void executeChild(TestExecutionNode child, ExecutionRequest request, TestExecutionContext parentContext) { protected void executeChild(TestExecutionNode child, ExecutionRequest request, TestExecutionContext parentContext,
TestExecutionContext childContext = createChildContext(child.getTestDescriptor(), parentContext); Object testInstance) {

TestExecutionContext childContext = createChildContext(child, parentContext, testInstance);
child.execute(request, childContext); child.execute(request, childContext);

}

private TestExecutionContext createChildContext(TestExecutionNode child, TestExecutionContext parentContext,
Object testInstance) {
Class<?> testClass = null;
Method testMethod = null;

if (child.getTestDescriptor() instanceof ClassTestDescriptor) {
//also handles ContextTestDescriptor which is subclass of CTD
testClass = ((ClassTestDescriptor) child.getTestDescriptor()).getTestClass();
}

if (child.getTestDescriptor() instanceof MethodTestDescriptor) {
MethodTestDescriptor methodTestDescriptor = (MethodTestDescriptor) child.getTestDescriptor();
testMethod = methodTestDescriptor.getTestMethod();
testClass = ((ClassTestDescriptor) methodTestDescriptor.getParent().get()).getTestClass();
}
return createContext(child.getTestDescriptor(), parentContext, testInstance, testMethod, testClass);
} }


protected TestExecutionContext createChildContext(TestDescriptor descriptor, TestExecutionContext parent) { protected TestExecutionContext createContext(TestDescriptor descriptor, TestExecutionContext parent,
Object testInstance, Method testMethod, Class testClass) {

return new TestExecutionContext() { return new TestExecutionContext() {


private final Map<String, Object> attributes = new HashMap<>(); private final Map<String, Object> attributes = new HashMap<>();
Expand All @@ -73,6 +99,21 @@ public Map<String, Object> getAttributes() {
public Optional<TestExecutionContext> getParent() { public Optional<TestExecutionContext> getParent() {
return Optional.ofNullable(parent); return Optional.ofNullable(parent);
} }

@Override
public Optional<Object> getTestInstance() {
return Optional.ofNullable(testInstance);
}

@Override
public Optional<Method> getTestMethod() {
return Optional.ofNullable(testMethod);
}

@Override
public Optional<Class<?>> getTestClass() {
return Optional.ofNullable(testClass);
}
}; };
} }


Expand Down

0 comments on commit c82f479

Please sign in to comment.