Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add test classes to an imported ear file and run server side with arquillian?

I want to create integration tests using arquillian. As deployment i want to use the ear that is also used to deploy in production.

So this is my deployment:

@Deployment(testable = true)
public static Archive<?> createDeployment() {
    return ShrinkWrap
            .create(ZipImporter.class, "test.ear")
            .importFrom(new File("simple-webservice-ear-1.0.0-SNAPSHOT.ear"))
            .as(EnterpriseArchive.class);
}

When i run my test class I get a java.lang.ClassNotFoundException because the test class is not found. I know I can set testable=false on the deployment but then the persistence extension doesn't work: see arquillian persistence extension doesn't work.

How can i solve this problem? Is there a way to add my test class to the deployment? Or should i create my deployment in another way?

like image 485
cremersstijn Avatar asked Feb 05 '13 17:02

cremersstijn


People also ask

What must you annotate an Arquillian integration test class with?

Write Our First Arquillian Test. If we're going to run our tests inside a container, we need to use the @Deployment annotation. Arquillian does not use the entire classpath to isolate the test archive. Instead, it uses the ShrinkWrap class, that is a Java API for creating archives.

What is Arquillian testing?

Arquillian is an integration and functional testing platform that can be used for Java middleware testing. With the main goal of making integration (and functional) tests as simple to write as unit tests, it brings the tests to the runtime environment, freeing developers from managing the runtime from within the test.

What is JBoss Arquillian?

As described in the Mission page of JBoss Arquillian website: Arquillian is an innovative and highly extensible testing platform for the JVM that enables developers to easily create automated integration, functional and acceptance tests for Java middleware.


2 Answers

You can manually add the test class to the war inside the ear like

WebArchive war = ear.getAsType(WebArchive.class, "/mywarname.war");
war.addClass(MyTestClass.class);
like image 184
cheesus Avatar answered Oct 03 '22 20:10

cheesus


You can use the way provided by Cheesus. When I am dealing with existing EAR, I prefer to separate the WAR that runs the tests, from the actual tests that I put in special JAR along with other testing EJBs. My deployment looks like this:

@Deployment
public static EnterpriseArchive createDeployment() {

    String path = System.getProperty(EAR_PATH);
    File f = new File(path);
    EnterpriseArchive ear = ShrinkWrap.createFromZipFile(EnterpriseArchive.class, f);

    final JavaArchive foobarEjb = ShrinkWrap.create(JavaArchive.class, "foobarEjb.jar");

    foobarEjb.addClasses(
                    MyTest1.class, 
                    MyTest2.class);
    ear.addAsModule(foobarEjb);


    final WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
            .addAsWebInfResource("WEB-INF/web.xml")
            .addAsWebResource("index.xhtml");

    ear.addAsModule(Testable.archiveToTest(war));

    modifyApplicationXML(ear);
    modifyJBossDeploymentStructure(ear);


    return ear;
}

Notice the methods to modify the application.xml and jboss-deployment-structure.xml. I need these to propertly initialize the JAR as an EjbModule inside the EAR.

Example how do I change application.xml:

private static void modifyApplicationXML(EnterpriseArchive ear) {
    Node node = ear.get("META-INF/application.xml");

    DescriptorImporter<ApplicationDescriptor> importer =  Descriptors.importAs(ApplicationDescriptor.class, "test");
    ApplicationDescriptor desc = importer.fromStream(node.getAsset().openStream());

    String xml = desc.exportAsString();

    // remove lib definition
    xml = xml.replaceAll("<library-directory>.*<\\/library-directory>", "");

    desc = (ApplicationDescriptor) importer.fromString(xml);
    // append foobar test ejbs
    desc.ejbModule("foobarEjb.jar");
    // append test war
    desc.webModule("test.war", "/test");
    // append lib definition
    desc.libraryDirectory("lib/");

    Asset asset = new StringAsset(desc.exportAsString());

    ear.delete(node.getPath());
    ear.setApplicationXML(asset);

}
like image 24
MartinTeeVarga Avatar answered Oct 03 '22 20:10

MartinTeeVarga