The question at this point is, how does Arquillian negotiate with the container to execute the test when the test framework is being invoked locally? Technially the mechanism is pluggable using another SPI, org.jboss.arquillian.spi.ContainerMethodExecutor. Arquillian provides a default implementation for remote servers which uses HTTP communication and an implementation for local tests, which works through direct execution of the test in the same JVM. Let's have a look at how the remote execution works.
The archive generator bundles and registers (in the web.xml descriptor) an HttpServlet, org.jboss.arquillian.protocol.servlet.ServletTestRunner, that responds to test execution GET requests. The test runner on the client side delegates to the org.jboss.arquillian.spi.ContainerMethodExecutor SPI implementation, which originates these test execution requests to transfer control to the container JVM. The name of the test class and the method to be executed are specified in the request query parameters named className and methodName, respectively.
When the test execution request is received, the servlet delegates to an implementation of the org.jboss.arquillian.spi.TestRunner SPI, passing it the name of the test class and the test method. TestRunner generates a test suite dynamically from the test class and method name and runs the suite (now within the context of the container).
The ServletTestRunner translates the native test result object of JUnit or TestNG into a org.jboss.arquillian.spi.TestResult and passes it back to the test executor on the client side by serializing the translated object into the response. The object gets encoded as either html or a serialized object, depending on the value of the outputMode request parameter that was passed to the servlet. Once the result has been transfered to the client-side test runner, the testing framework (JUnit or TestNG) wraps up the run of the test as though it had been executed in the same JVM.
Now you should have an understanding for how tests can be executed inside the container, but still be executed using existing IDE, Ant and Maven test plugins without any modification. Perhaps you have even started thinking about ways in which you can enhance or extend Arquillian. But there's still one challenge that remains for developing tests with Arquillian. How do you debug test? We'll look at how to hook a debugger into the test execution process in the next chapter.