-
-
Save rherrmann/7447571 to your computer and use it in GitHub Desktop.
/******************************************************************************* | |
* Copyright (c) 2013,2014 Rüdiger Herrmann | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* Rüdiger Herrmann - initial API and implementation | |
* Matt Morrissette - allow to use non-static inner IgnoreConditions | |
******************************************************************************/ | |
package com.codeaffine.test; | |
import java.lang.annotation.ElementType; | |
import java.lang.annotation.Retention; | |
import java.lang.annotation.RetentionPolicy; | |
import java.lang.annotation.Target; | |
import java.lang.reflect.Modifier; | |
import org.junit.Assume; | |
import org.junit.rules.MethodRule; | |
import org.junit.runners.model.FrameworkMethod; | |
import org.junit.runners.model.Statement; | |
public class ConditionalIgnoreRule implements MethodRule { | |
public interface IgnoreCondition { | |
boolean isSatisfied(); | |
} | |
@Retention(RetentionPolicy.RUNTIME) | |
@Target({ElementType.METHOD}) | |
public @interface ConditionalIgnore { | |
Class<? extends IgnoreCondition> condition(); | |
} | |
@Override | |
public Statement apply( Statement base, FrameworkMethod method, Object target ) { | |
Statement result = base; | |
if( hasConditionalIgnoreAnnotation( method ) ) { | |
IgnoreCondition condition = getIgnoreContition( target, method ); | |
if( condition.isSatisfied() ) { | |
result = new IgnoreStatement( condition ); | |
} | |
} | |
return result; | |
} | |
private static boolean hasConditionalIgnoreAnnotation( FrameworkMethod method ) { | |
return method.getAnnotation( ConditionalIgnore.class ) != null; | |
} | |
private static IgnoreCondition getIgnoreContition( Object target, FrameworkMethod method ) { | |
ConditionalIgnore annotation = method.getAnnotation( ConditionalIgnore.class ); | |
return new IgnoreConditionCreator( target, annotation ).create(); | |
} | |
private static class IgnoreConditionCreator { | |
private final Object target; | |
private final Class<? extends IgnoreCondition> conditionType; | |
IgnoreConditionCreator( Object target, ConditionalIgnore annotation ) { | |
this.target = target; | |
this.conditionType = annotation.condition(); | |
} | |
IgnoreCondition create() { | |
checkConditionType(); | |
try { | |
return createCondition(); | |
} catch( RuntimeException re ) { | |
throw re; | |
} catch( Exception e ) { | |
throw new RuntimeException( e ); | |
} | |
} | |
private IgnoreCondition createCondition() throws Exception { | |
IgnoreCondition result; | |
if( isConditionTypeStandalone() ) { | |
result = conditionType.newInstance(); | |
} else { | |
result = conditionType.getDeclaredConstructor( target.getClass() ).newInstance( target ); | |
} | |
return result; | |
} | |
private void checkConditionType() { | |
if( !isConditionTypeStandalone() && !isConditionTypeDeclaredInTarget() ) { | |
String msg | |
= "Conditional class '%s' is a member class " | |
+ "but was not declared inside the test case using it.\n" | |
+ "Either make this class a static class, " | |
+ "standalone class (by declaring it in it's own file) " | |
+ "or move it inside the test case using it"; | |
throw new IllegalArgumentException( String.format ( msg, conditionType.getName() ) ); | |
} | |
} | |
private boolean isConditionTypeStandalone() { | |
return !conditionType.isMemberClass() || Modifier.isStatic( conditionType.getModifiers() ); | |
} | |
private boolean isConditionTypeDeclaredInTarget() { | |
return target.getClass().isAssignableFrom( conditionType.getDeclaringClass() ); | |
} | |
} | |
private static class IgnoreStatement extends Statement { | |
private final IgnoreCondition condition; | |
IgnoreStatement( IgnoreCondition condition ) { | |
this.condition = condition; | |
} | |
@Override | |
public void evaluate() { | |
Assume.assumeTrue( "Ignored by " + condition.getClass().getSimpleName(), false ); | |
} | |
} | |
} |
Upon further investigation I dicovered that having a @before setUp() causes this failure. If I remove the @ConditionalIgnore from my test, it passes just fine. The setUp() - with the @ConditionalIgnore - always fails.
My source is here: https://sourceforge.net/p/genieos/code-0/HEAD/tree/trunk/demos/src/test/java/net/sourceforge/genieos/demos/WindowsLaunchTest.java
Any idea?
TIA.
Just tried to run this on my Linux machine: the @before setUp() is still run.
Am I using this wrong?
Found my issue: I declared the NotRunningOnWindows class inside of my SomeTest class, and so it has to be explicitly static.
I have fixed the above class to work with classes declared inside your test case (i.e. anonymous inner member classes). The fix is in my fork of this Gist available at: https://gist.github.com/yinzara/9980184
https://issues.apache.org/jira/browse/GEODE-167 - ConditionalIgnore from Apache.
I tried this solution with Espresso but doesn't work.
Following is my observation:
If I have four test cases: A(), B(), C(), D() and I applied @ConditionalIgnore on B() method, then C() and D() also ignored.
Can you please help me on this.
Does this work with any JUnit4? I am trying this with JUnit4.11, and the exact condition you described at http://www.codeaffine.com/2013/11/18/a-junit-rule-to-conditionally-ignore-tests/ All I get is: java.lang.RuntimeException: java.lang.InstantiationException: xyzTest$NotRunningOnWindows
at com.codeaffine.junit.ignore.ConditionalIgnoreRule.newCondition(ConditionalIgnoreRule.java:61)
at com.codeaffine.junit.ignore.ConditionalIgnoreRule.getIgnoreContition(ConditionalIgnoreRule.java:52)
at com.codeaffine.junit.ignore.ConditionalIgnoreRule.apply(ConditionalIgnoreRule.java:38)
at org.junit.runners.BlockJUnit4ClassRunner.withMethodRules(BlockJUnit4ClassRunner.java:349)
at org.junit.runners.BlockJUnit4ClassRunner.withRules(BlockJUnit4ClassRunner.java:339)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:256)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.InstantiationException: net.sourceforge.genieos.demos.WindowsLaunchTest$NotRunningOnWindows
at java.lang.Class.newInstance0(Class.java:359)
at java.lang.Class.newInstance(Class.java:327)
at com.codeaffine.junit.ignore.ConditionalIgnoreRule.newCondition(ConditionalIgnoreRule.java:57)
... 21 more