8 Replies Latest reply on Jan 25, 2012 4:09 AM by daniel_spasojevic

    @Before, @After, @BeforeClass, @AfterClass

    ssilvert

      I'm surprised that nobody has asked about this, but my searches come up empty.

       

      Is there Arquillian support for JUnit 4 @Before, @After, @BeforeClass, and @AfterClass annotations?

       

      Right now it looks like they get executed before the test is deployed to the container.  But most of the time you want these to execute in support of your in-container tests.

       

      In the JSFUnit world, most people put setup code in a setUp() method, which Cactus executes in-container by honoring the JUnit 3 contract for junit.framework.TestCase.

       

      Stan

        • 1. Re: @Before, @After, @BeforeClass, @AfterClass
          dan.j.allen

          Currently, they don't receive the test enrichment. In fact, the question just came up in blog entry comment today. There's a long-standing open issue to support this: ARQ-56. As a workaround, I've been explicitly invoking a before method, but obviously that is not ideal.

           

          Alex Smirmov also suggested adding support for @BeforeDeployment and @AfterDeployment lifecycle methods. The first would possibly give the test writer a chance to inspect the final test archive or do some other container setup. I'm unclear how much of an edge case these would be, or whether they turn out to be essential hooks.

          • 2. Re: @Before, @After, @BeforeClass, @AfterClass
            aslak

            I have a working branch for support for this in my git repo, but has not been pushed upstream since there is no TestNG support for the same yet.(working with Cedric on this..)

            • 3. Re: @Before, @After, @BeforeClass, @AfterClass
              ssilvert

              Aslak Knutsen wrote:

               

              I have a working branch for support for this in my git repo, but has not been pushed upstream since there is no TestNG support for the same yet.(working with Cedric on this..)

              Great.  I'll be looking for that in a future version.

               

              Stan

              • 4. Re: @Before, @After, @BeforeClass, @AfterClass
                ssilvert

                It looks like the test class is "new'ed" every time a test is run.  So if I have two methods annotated with @Test then the no-arg constructor for my test class will be called twice.

                 

                I could use that as my @Before method.  Is that the way it will always work from now on?  It seems that you actually shouldn't create a new instance of the test class for each test though.

                 

                Stan

                • 5. Re: @Before, @After, @BeforeClass, @AfterClass
                  jaikiran

                  Stan Silvert wrote:

                   

                  It looks like the test class is "new'ed" every time a test is run.  So if I have two methods annotated with @Test then the no-arg constructor for my test class will be called twice.

                   

                  I could use that as my @Before method.  Is that the way it will always work from now on?  It seems that you actually shouldn't create a new instance of the test class for each test though.

                   

                  Stan

                  This explains why the instance is created per test http://martinfowler.com/bliki/JunitNewInstance.html

                  • 6. Re: @Before, @After, @BeforeClass, @AfterClass
                    ssilvert

                    Thanks Jaikiran.  That changed my mind.  Fowler is right.

                     

                    Stan

                    • 7. Re: @Before, @After, @BeforeClass, @AfterClass
                      samjaya

                      yep.
                      I noticed that the @BeforeClass method is run after every test method when it should only run once per test class.

                      • 8. Re: @Before, @After, @BeforeClass, @AfterClass
                        daniel_spasojevic

                        Hi,

                         

                        I am wondering if the TestNG @AfterClass and @AfterMethods are supported yet.

                         

                        It seems unpredictable whether methods annotated with @AfterX will be run in container or not.

                         

                        Fo example, one of our test groups extends a common base class (that extends ArquillianTestCase). That base class has a method with a @AfterClass annotation. For one of the concrete classes, that @AfterClass method is called in container:

                         

                        19:55:25,656 INFO  [business] (management-handler-threads - 54) Using user transaction [Transaction: unknown]: java.lang.Exception

                                  at au.com.allhomes.batch.ejb.model.schedule.query.BaseSchedulableTest.unpausePausedJobs(BaseSchedulableTest.java:32) [all-batch-ejb.jar:]

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_23]

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [:1.6.0_23]

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [:1.6.0_23]

                                  at java.lang.reflect.Method.invoke(Method.java:616) [:1.6.0_23]

                                  at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80) [arquillian-service:]

                                  at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:543) [arquillian-service:]

                                  at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:212) [arquillian-service:]

                                  at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138) [arquillian-service:]

                                  at org.testng.internal.TestMethodWorker.invokeAfterClassMethods(TestMethodWorker.java:225) [arquillian-service:]

                                  at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:114) [arquillian-service:]

                                  at org.testng.TestRunner.privateRun(TestRunner.java:758) [arquillian-service:]

                                  at org.testng.TestRunner.run(TestRunner.java:613) [arquillian-service:]

                                  at org.testng.SuiteRunner.runTest(SuiteRunner.java:334) [arquillian-service:]

                                  at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) [arquillian-service:]

                                  at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) [arquillian-service:]

                                  at org.testng.SuiteRunner.run(SuiteRunner.java:240) [arquillian-service:]

                                  at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) [arquillian-service:]

                                  at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) [arquillian-service:]

                                  at org.testng.TestNG.runSuitesSequentially(TestNG.java:1137) [arquillian-service:]

                                  at org.testng.TestNG.runSuitesLocally(TestNG.java:1062) [arquillian-service:]

                                  at org.testng.TestNG.run(TestNG.java:974) [arquillian-service:]

                                  at org.jboss.arquillian.testng.container.TestNGTestRunner.execute(TestNGTestRunner.java:53) [arquillian-service:]

                                  at org.jboss.arquillian.protocol.jmx.JMXTestRunner.runTestMethodInternal(JMXTestRunner.java:128) [arquillian-service:]

                                  at org.jboss.arquillian.protocol.jmx.JMXTestRunner.runTestMethod(JMXTestRunner.java:107) [arquillian-service:]

                                  at org.jboss.as.arquillian.service.ArquillianService$ExtendedJMXTestRunner.runTestMethod(ArquillianService.java:226) [arquillian-service:]

                         

                        For one of the other concrete classes, the @AfterClass is called outside the container:

                         

                        INFO [business] Using user transaction [null]

                        java.lang.Exception

                                at au.com.allhomes.batch.ejb.model.schedule.query.BaseSchedulableTest.unpausePausedJobs(BaseSchedulableTest.java:32)

                                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                at java.lang.reflect.Method.invoke(Method.java:616)

                                at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)

                                at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:543)

                                at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:212)

                                at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)

                                at org.testng.internal.TestMethodWorker.invokeAfterClassMethods(TestMethodWorker.java:225)

                                at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:114)

                                at org.testng.TestRunner.privateRun(TestRunner.java:758)

                                at org.testng.TestRunner.run(TestRunner.java:613)

                                at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)

                                at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)

                                at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)

                                at org.testng.SuiteRunner.run(SuiteRunner.java:240)

                                at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)

                                at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87)

                                at org.testng.TestNG.runSuitesSequentially(TestNG.java:1137)

                                at org.testng.TestNG.runSuitesLocally(TestNG.java:1062)

                                at org.testng.TestNG.run(TestNG.java:974)

                                at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:103)

                                at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:58)

                                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                                at java.lang.reflect.Method.invoke(Method.java:616)

                         

                        If I comment out the @AfterX annotations, then the @Test methods themselves are all run in the container as expected.

                         

                        Any pointers would be appreciated.

                         

                        Thanks,

                        -Dan