5 Replies Latest reply on Apr 10, 2017 3:46 AM by omihalyi

    Arquillian / TestNG method invocation sequence

    dmiklancic

      Version:1.0 StartHTML:0000000167 EndHTML:0000029271 StartFragment:0000000454 EndFragment:0000029255        

       

      Running Arquillian managed container, JBoss 7.0.2

       

      Sequence:

      1. Start JBoss
      2. TestNG Before Suite (performed out of container; no test class injections)
      3. TestNG Before Test (performed out of container; no test class injections)
      4. Deploy arquillian and @Deployment war
      5. TestNG Before Class (performed out of container; no test class injections)
      6. TestNG Before Method (performed out of container; no test class injections)
      7. TestNG Before Suite (in container; no injections)
      8. TestNG Before Test (in container; no injections)
      9. TestNG Before Class (in container; no injections)
      10. TestNG Before Method (in container; test class INJECTIONS available)
      11. TestNG test method (in container; test class INJECTIONS available)
      12. TestNG After Method (in container; test class INJECTIONS available)
      13. TestNG After Class (in container; test class INJECTIONS available)
      14. TestNG After Test (in container; test class INJECTIONS available)
      15. TestNG After Suite (in container; test class INJECTIONS available)
      16. TestNG After Method (performed out of container; no test class injections)
      17. TestNG Before Method (performed out of container; no test class injections)
      18. TestNG Before Suite (in container; no injections)
      19. TestNG Before Test (in container; no injections)
      20. TestNG Before Class (in container; no injections)
      21. TestNG Before Method (in container; test class INJECTIONS available)
      22. TestNG test method (in container; test class INJECTIONS available)
      23. TestNG After Method (in container; test class INJECTIONS available)
      24. TestNG After Class (in container; test class INJECTIONS available)
      25. TestNG After Test (in container; test class INJECTIONS available)
      26. TestNG After Suite (in container; test class INJECTIONS available)
      27. TestNG After Method (performed out of container; no test class injections)
      28. TestNG After Class (performed out of container; no test class injections)
      29. Undeploy war
      30. TestNG After Test (performed out of container; no test class injections)
      31. TestNG After Suite (performed out of container; no test class injections)
      32. Undeploy arquillian
      33. Stop JBoss (?)

       

      From what I observe, there are two overlapping TestNG lifecycles being performed.  One lifecycle (in black text) is performed on the client side; the other lifecycle is performed in its entirety for each test method inside the container (red text).  It appears that test class injections, resources, etc., are only available in the BeforeMethod, test methods and AfterMethod phases of the lifecycle (although the injections appear to “hang around” in the AfterClass, AfterTest and AfterSuite methods).

       

      Interestingly, if a test class @Resource is coded, the BeforeMethod and following phases are NOT executed in container (ARQ-563), yet the test “passes”.  Note:  @Inject seems to work as documented.

       

      Following is a log trace supporting the above summary (extraneous entires have been omitted).

       

      Question: Is this how Arquillian and TestNG are designed to work together?  It seems to follow the diagram provided in the Arquillian documentation, except the diagram does not really portray the overlapping lifecycles.

       

      If this is the case, can one assume the client-side lifecycle is for arquillian's purposes (i.e. to start / stop services, deploy / undeploy wars)?  If so, how can one code a BeforeMethod that is only invoked when running in container?  Right now, the BeforeMethod executes both on the client and in container and if it depends on an injected object, it will fail when running on the client-side since the injections are not available there. (I am current coding:  if (injectedObject != null) to distinguish between the two invocations.

       

      -------------------------------------------------------

      T E S T S

      -------------------------------------------------------

      Running TestSuite

      Oct 6, 2011 8:00:26 AM org.jboss.as.arquillian.container.managed.ManagedDeployableContainer startInternal

      INFO: Starting container with: [java, -Xmx512m, -XX:MaxPermSize=128m, -Djboss.home.dir=/Users/miklandj/Development/JBoss7/jboss-as-web-7.0.2.Final,

      . . .

      08:00:30,526 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) Bound data source [java:/ProcessNetworkDS]

      . . .

      08:00:31,021 INFO  [org.jboss.as] (Controller Boot Thread) JBoss AS 7.0.2.Final "Arc" started in 3779ms - Started 129 of 187 services (58 services are passive or on-demand)

      . . .

      [08:00:32,585] INFO (SecurityDataServiceTest.java:84) - Before suite: session bean null, user tx null

      [08:00:32,591] INFO (SecurityDataServiceTest.java:89) - Before test: session bean null, user tx null

      . . .

      [08:00:35,515] INFO (ArquillianServiceDeployer.java:56) - Deploy arquillian service: arquillian-service: 1549 assets

      . . .

      08:00:47,042 INFO  [org.jboss.web] (MSC service thread 1-3) registering web context: /securityDataService

      08:00:47,063 INFO  [org.jboss.as.server.controller] (pool-1-thread-1) Deployed "securityDataService.war"

      . . .

      [08:00:47,350] INFO (SecurityDataServiceTest.java:97) - Before class: session bean null, user tx null

      [08:00:47,370] INFO (SecurityDataServiceTest.java:102) - Before method: session bean null, user tx null

       

      08:00:48,169 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     84  ) Before suite: session bean null, user tx null

      08:00:48,170 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     89  ) Before test: session bean null, user tx null

      08:00:48,173 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     97  ) Before class: session bean null, user tx null

      08:00:48,263 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     102 ) Before method: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

       

      08:00:48,877 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) Loaded user security tables.

       

      08:00:48,959 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     125 ) After method: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

      08:00:48,961 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     120 ) After class: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown,

      08:00:48,963 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     116 ) After test: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

      08:00:48,964 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     111 ) After suite: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

       

      [08:00:48,990] INFO (SecurityDataServiceTest.java:125) - After method: session bean null, user tx null

      [08:00:48,993] INFO (SecurityDataServiceTest.java:102) - Before method: session bean null, user tx null

       

      08:00:49,080 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     84  ) Before suite: session bean null, user tx null

      08:00:49,081 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     89  ) Before test: session bean null, user tx null

      08:00:49,083 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     97  ) Before class: session bean null, user tx null

      08:00:49,087 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     102 ) Before method: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

       

      08:00:49,209 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) Loaded user security tables.

       

      08:00:49,267 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     125 ) After method: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

      08:00:49,269 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     120 ) After class: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

      08:00:49,270 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     116 ) After test: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

      08:00:49,271 INFO  [stdout] (RMI TCP Connection(3)-127.0.0.1) (service.SecurityDataServiceTest     111 ) After suite: session bean Proxy for view class: com.bp.cpr.pn.business.user.security.service.SecurityDataService of EJB: SecurityDataServiceBean, user tx Transaction: unknown

       

      [08:00:49,274] INFO (SecurityDataServiceTest.java:125) - After method: session bean null, user tx null

      [08:00:49,753] INFO (SecurityDataServiceTest.java:120) - After class: session bean null, user tx null

       

      08:00:49,896 INFO  [org.jboss.weld] (MSC service thread 1-4) Stopping weld service

      08:00:49,900 INFO  [org.jboss.jpa] (MSC service thread 1-4) stopping Persistence Unit Service 'securityDataService.war#businessUserSecurity'

      08:00:49,913 INFO  [org.jboss.as.server.controller] (pool-1-thread-1) Undeployed "securityDataService.war"

      08:00:49,974 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) Stopped deployment securityDataService.war in 164ms

       

      [08:00:49,981] INFO (SecurityDataServiceTest.java:116) - After test: session bean null, user tx null

      [08:00:49,992] INFO (SecurityDataServiceTest.java:111) - After suite: session bean null, user tx null

       

      [08:00:49,999] INFO (ArquillianServiceDeployer.java:71) - Undeploy arquillian service: arquillian-service: 1549 assets

      08:00:50,073 INFO  [org.jboss.as.server.controller] (pool-1-thread-1) Undeployed "arquillian-service"

      08:00:50,085 INFO  [org.jboss.as.osgi] (MSC service thread 1-1) JBAS011922: Unregister module: Module "deployment.arquillian-service:main" from Service Module Loader

      08:00:50,086 ERROR [org.jboss.osgi.framework.internal.BundleManager] (MSC service thread 1-1) Cannot find bundle associated with module: deployment.arquillian-service:main

      08:00:50,106 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) Stopped deployment arquillian-service in 73ms

      Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 24.802 sec

       

      Results :

       

      Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

       

      [INFO] ------------------------------------------------------------------------

      [INFO] BUILD SUCCESS

      [INFO] ------------------------------------------------------------------------

      [INFO] Total time: 47.933s

      [INFO] Finished at: Thu Oct 06 08:00:50 EDT 2011

      [INFO] Final Memory: 49M/110M

      [INFO] ------------------------------------------------------------------------

        • 1. Re: Arquillian / TestNG method invocation sequence
          daniel_spasojevic

          Hi Daniel,

           

          Did you find a more elegant work around than checking for the injected resource? I am dealing with the same issue right now... be happy to hear that you have sorted out the issue.

           

          Thanks,

          -Dan

          • 2. Re: Arquillian / TestNG method invocation sequence
            suikast42

            Hey Daniel did you find a workarround for this issue?? I'm in the same trouble.

            • 3. Re: Arquillian / TestNG method invocation sequence
              zellus

              Seems like switching back to JUnit or doing some if/else.

              • 4. Re: Arquillian / TestNG method invocation sequence
                eric.george

                I was using the "check for injected object null" technique for a while, but I found this check to be more elegant:

                 

                public static boolean inContainer() {

                   return AuthenticatedTest.class.getClassLoader().toString().contains("MyEar.ear");

                }

                 

                The classloader name (at least in WildFly 9.0) includes the ear name, but the "outside" one does not.

                • 5. Re: Arquillian / TestNG method invocation sequence
                  omihalyi

                  It seems that it is not possible to avoid having 2 lifecycles with TestNG, or Arquillian developers at least don't know how to avoid it.

                   

                  JUnit provides a concept of runners, where every runner has complete control over how a test is executed. Does anyone know if TestNG provides a similar concept?

                  The current solution for Arquillian in TestNG is only to provide hooks into the executed tests, so it's possible to add more methods to run, but not avoid running methods in the test (e.g. Before). The only thing that can be completely overriden is the actual test methods: See the TestNG docs.

                   

                  I'm facing the same issue now when trying to create an Arquillian extensions for Junit5 - extensions can only add listeners, but I can't find a way to disable test normal execution and trigger execution in an Arquillian container.