[jboss-svn-commits] JBoss Common SVN: r4531 - in arquillian/trunk: junit/src/main/java/org/jboss/arquillian/junit and 5 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jun 17 14:14:04 EDT 2010


Author: aslak
Date: 2010-06-17 14:14:03 -0400 (Thu, 17 Jun 2010)
New Revision: 4531

Added:
   arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/JUnitTestRunnerTestCase.java
   arquillian/trunk/testng/src/test/java/org/jboss/arquillian/testng/TestNGTestRunnerTestCase.java
Modified:
   arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DeployableTestBuilder.java
   arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/Arquillian.java
   arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/JUnitTestRunner.java
   arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/testspi/TestDeployableContainer.java
   arquillian/trunk/protocols/local/src/main/java/org/jboss/arquillian/protocol/local/LocalMethodExecutor.java
   arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestListener.java
   arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestNGTestRunner.java
Log:
ARQ-37 Added support for @Test(expected=Exception.class) in JUnit and @Test(expectedException=Exception.class), @ExpectedException(Exception.class) in TestNG. Exposes issue related to Arquillians internal TestResult state, see ARQ-181.

Modified: arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DeployableTestBuilder.java
===================================================================
--- arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DeployableTestBuilder.java	2010-06-15 17:48:23 UTC (rev 4530)
+++ arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DeployableTestBuilder.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -50,6 +50,11 @@
    {
       return DeployableTestBuilder.profile;
    }
+   
+   public static void clearProfile() 
+   {
+      DeployableTestBuilder.profile = null;
+   }
 
    /**
     * @return

Modified: arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/Arquillian.java
===================================================================
--- arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/Arquillian.java	2010-06-15 17:48:23 UTC (rev 4530)
+++ arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/Arquillian.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -47,9 +47,17 @@
  */
 public class Arquillian extends BlockJUnit4ClassRunner
 {
-   private static ThreadLocal<TestRunnerAdaptor> deployableTest = new ThreadLocal<TestRunnerAdaptor>();
-   
    /*
+    * @HACK
+    * JUnit Hack:
+    * In JUnit a Exception is thrown and verified/swallowed if @Test(expected) is set. We need to transfer this
+    * Exception back to the client so the client side can throw it again. This to avoid a incontainer working but failing
+    * on client side due to no Exception thrown. 
+    */
+   public static ThreadLocal<Throwable> caughtTestException = new ThreadLocal<Throwable>();
+
+   /*
+    * @HACK
     * Eclipse hack:
     * When running multiple TestCases, Eclipse will create a new runner for each of them.
     * This results in that AfterSuite is call pr TestCase, but BeforeSuite only on the first created instance.
@@ -57,6 +65,8 @@
     * was the last one created. The last one created is the only one allowed to call AfterSuite.
     */
    private static ThreadLocal<Arquillian> lastCreatedRunner = new ThreadLocal<Arquillian>();
+
+   private static ThreadLocal<TestRunnerAdaptor> deployableTest = new ThreadLocal<TestRunnerAdaptor>();
    
    public Arquillian(Class<?> klass) throws InitializationError
    {
@@ -75,7 +85,7 @@
             throw new InitializationError(Arrays.asList((Throwable)e));
          }
       }
-      /* TODO: HACK
+      /* @HACK
        *  If in-container, the Thread will be reused between multiple TestRuns.
        *  We need to call BeginSuite before everyone. But only once if not. 
        */
@@ -229,8 +239,17 @@
             {
                public void invoke() throws Throwable
                {
-                  Object parameterValues = TestEnrichers.enrich(deployableTest.get().getActiveContext(), getMethod());
-                  method.invokeExplosively(test, (Object[])parameterValues);
+                  try
+                  {
+                     Object parameterValues = TestEnrichers.enrich(deployableTest.get().getActiveContext(), getMethod());
+                     method.invokeExplosively(test, (Object[])parameterValues);
+                  } 
+                  catch (Throwable e) 
+                  {
+                     // Force a way to return the thrown Exception from the Container the client. 
+                     caughtTestException.set(e);
+                     throw e;
+                  }
                }
                
                public Method getMethod()

Modified: arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/JUnitTestRunner.java
===================================================================
--- arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/JUnitTestRunner.java	2010-06-15 17:48:23 UTC (rev 4530)
+++ arquillian/trunk/junit/src/main/java/org/jboss/arquillian/junit/JUnitTestRunner.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -21,9 +21,12 @@
 import org.jboss.arquillian.spi.TestResult;
 import org.jboss.arquillian.spi.TestRunner;
 import org.jboss.arquillian.spi.TestResult.Status;
+import org.junit.Test;
+import org.junit.runner.Description;
 import org.junit.runner.JUnitCore;
 import org.junit.runner.Request;
 import org.junit.runner.Result;
+import org.junit.runner.notification.RunListener;
 
 /**
  * JUnitTestRunner
@@ -37,14 +40,27 @@
 {
    public TestResult execute(Class<?> testClass, String methodName)
    {
+      final ExpectedExceptionHolder exceptionHolder = new ExpectedExceptionHolder();
       DeployableTestBuilder.setProfile(ContainerProfile.CONTAINER);
       JUnitCore runner = new JUnitCore();
+      runner.addListener(new RunListener() {
+         @Override
+         public void testFinished(Description description) throws Exception
+         {
+            Test test = description.getAnnotation(Test.class);
+            if(test != null && test.expected() != Test.None.class)
+            {
+               exceptionHolder.setException(Arquillian.caughtTestException.get());
+            }
+         }
+      });
       Result result = runner.run(
             Request.method(
                   testClass, 
                   methodName));
-      
-      return convertToTestResult(result);
+     
+      DeployableTestBuilder.clearProfile();
+      return convertToTestResult(result, exceptionHolder.getException());
    }
 
    /**
@@ -53,11 +69,10 @@
     * @param result JUnit Test Run Result
     * @return The TestResult representation of the JUnit Result
     */
-   private TestResult convertToTestResult(Result result) 
+   private TestResult convertToTestResult(Result result, Throwable expectedException) 
    {
       Status status = Status.PASSED;
-      Throwable throwable = null;
-      
+      Throwable throwable = expectedException;
       if(result.getFailureCount() > 0) 
       {
          status = Status.FAILED;
@@ -69,4 +84,18 @@
       }
       return new TestResult(status, throwable);
    }
+   
+   private class ExpectedExceptionHolder {
+      private Throwable exception = null;
+      
+      public void setException(Throwable exception)
+      {
+         this.exception = exception;
+      }
+      
+      public Throwable getException()
+      {
+         return exception;
+      }
+   }
 }

Added: arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/JUnitTestRunnerTestCase.java
===================================================================
--- arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/JUnitTestRunnerTestCase.java	                        (rev 0)
+++ arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/JUnitTestRunnerTestCase.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.arquillian.junit;
+
+
+import org.jboss.arquillian.spi.TestResult;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class JUnitTestRunnerTestCase
+{
+   @Test
+   public void shouldReturnPassedTest() throws Exception 
+   {
+      JUnitTestRunner runner = new JUnitTestRunner();
+      TestResult result = runner.execute(JUnitTestRunnerTestCase.class, "shouldProvidePassingTestToRunner");
+      
+      Assert.assertNotNull(result);
+      Assert.assertEquals(TestResult.Status.PASSED, result.getStatus());
+      Assert.assertNull(result.getThrowable());
+   }
+
+   @Test
+   public void shouldReturnExceptionOnPassedTest() throws Exception 
+   {
+      // Simulate setting the Exception like Arquillian would. This is a JUnit hack to avoid JUnit Swallowing the Exception.
+      Arquillian.caughtTestException.set(new IllegalArgumentException());
+      JUnitTestRunner runner = new JUnitTestRunner();
+      TestResult result = runner.execute(JUnitTestRunnerTestCase.class, "shouldProvideExpectedExceptionToRunner");
+      
+      Assert.assertNotNull(result);
+      Assert.assertEquals(TestResult.Status.PASSED, result.getStatus());
+      Assert.assertNotNull(result.getThrowable());
+      Assert.assertEquals(IllegalArgumentException.class, result.getThrowable().getClass());
+   }
+   
+   @Test(expected = IllegalArgumentException.class)
+   public void shouldProvideExpectedExceptionToRunner() throws Exception
+   {
+      throw new IllegalArgumentException();
+   }
+   
+   @Test
+   public void shouldProvidePassingTestToRunner() throws Exception 
+   {
+      Assert.assertTrue(true);
+   }
+}

Modified: arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/testspi/TestDeployableContainer.java
===================================================================
--- arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/testspi/TestDeployableContainer.java	2010-06-15 17:48:23 UTC (rev 4530)
+++ arquillian/trunk/junit/src/test/java/org/jboss/arquillian/junit/testspi/TestDeployableContainer.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -86,6 +86,10 @@
             }
             catch (Throwable e) 
             {
+               /*
+                *  TODO: the internal state TestResult is FAILED with Exception set, but it might have passed
+                *  due to the TestFrameworks ExpectedExceptions. We need to know this information to set the correct state.
+                */
                result.setStatus(Status.FAILED);
                result.setThrowable(e);
             }

Modified: arquillian/trunk/protocols/local/src/main/java/org/jboss/arquillian/protocol/local/LocalMethodExecutor.java
===================================================================
--- arquillian/trunk/protocols/local/src/main/java/org/jboss/arquillian/protocol/local/LocalMethodExecutor.java	2010-06-15 17:48:23 UTC (rev 4530)
+++ arquillian/trunk/protocols/local/src/main/java/org/jboss/arquillian/protocol/local/LocalMethodExecutor.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -42,6 +42,11 @@
       }
       catch (final Throwable e) 
       {
+         /*
+          *  TODO: the internal state TestResult is FAILED with Exception set, but it might have passed
+          *  due to the TestFrameworks ExpectedExceptions. We need to know this information to set the correct state.
+          */
+
          result.setStatus(Status.FAILED);
          result.setThrowable(e);
       }

Modified: arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestListener.java
===================================================================
--- arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestListener.java	2010-06-15 17:48:23 UTC (rev 4530)
+++ arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestListener.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -74,6 +74,14 @@
       {
          return new TestResult(Status.SKIPPED);
       }
-      return new TestResult(Status.PASSED); 
+      if(context.getPassedTests().size() > 0) 
+      {
+         return new TestResult(
+               Status.PASSED, 
+               context.getPassedTests().getAllResults().iterator().next().getThrowable());
+      } 
+      return new TestResult(
+            Status.FAILED, 
+            new RuntimeException("Unknown test result: " + context).fillInStackTrace());
    }
 }

Modified: arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestNGTestRunner.java
===================================================================
--- arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestNGTestRunner.java	2010-06-15 17:48:23 UTC (rev 4530)
+++ arquillian/trunk/testng/src/main/java/org/jboss/arquillian/testng/TestNGTestRunner.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -53,6 +53,7 @@
       
       runner.run();
 
+      DeployableTestBuilder.clearProfile();
       return resultListener.getTestResult(); 
    }
    

Added: arquillian/trunk/testng/src/test/java/org/jboss/arquillian/testng/TestNGTestRunnerTestCase.java
===================================================================
--- arquillian/trunk/testng/src/test/java/org/jboss/arquillian/testng/TestNGTestRunnerTestCase.java	                        (rev 0)
+++ arquillian/trunk/testng/src/test/java/org/jboss/arquillian/testng/TestNGTestRunnerTestCase.java	2010-06-17 18:14:03 UTC (rev 4531)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.arquillian.testng;
+
+import org.jboss.arquillian.spi.TestResult;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestNGTestRunnerTestCase
+{
+   @Test
+   public void shouldReturnPassedTest() throws Exception 
+   {
+      TestNGTestRunner runner = new TestNGTestRunner();
+      TestResult result = runner.execute(TestNGTestRunnerTestCase.class, "shouldProvidePassingTestToRunner");
+      
+      Assert.assertNotNull(result);
+      Assert.assertEquals(TestResult.Status.PASSED, result.getStatus());
+      Assert.assertNull(result.getThrowable());
+   }
+
+   @Test
+   public void shouldReturnExceptionOnPassedTest() throws Exception 
+   {
+      TestNGTestRunner runner = new TestNGTestRunner();
+      TestResult result = runner.execute(TestNGTestRunnerTestCase.class, "shouldProvideExpectedExceptionToRunner");
+      
+      Assert.assertNotNull(result);
+      Assert.assertEquals(TestResult.Status.PASSED, result.getStatus());
+      Assert.assertNotNull(result.getThrowable());
+      Assert.assertEquals(IllegalArgumentException.class, result.getThrowable().getClass());
+   }
+   
+   @org.testng.annotations.Test(expectedExceptions = IllegalArgumentException.class)
+   public void shouldProvideExpectedExceptionToRunner() throws Exception
+   {
+      throw new IllegalArgumentException();
+   }
+   
+   @org.testng.annotations.Test
+   public void shouldProvidePassingTestToRunner() throws Exception 
+   {
+      Assert.assertTrue(true);
+   }
+}



More information about the jboss-svn-commits mailing list