Ταχύτερη εξοικείωση με τη χρήση του Forge

Authors: Paul Bakker, Lincoln Baxter, III Translator: Tolis Emmanouilidis Language:
Last Update:Apr 28, 2013

Ο οδηγός αυτός στοχεύει στην εξοικείωση με το Arquillian plugin για το JBoss Forge. Με την ολοκλήρωση του οδηγού, θα είσαι σε θέση να:

  • Εγκαταστήσεις το Arquillian plugin στο Forge
  • Χρησιμοποιήσεις το plugin ώστε να προσθέσεις την υποδομή του Arquillian σε ένα Maven-based Java project
  • Δημιουργήσεις ένα component και το αντίστοιχο Arquillian test
  • Εκτελέσεις ένα Arquillian τέστ σε πολλούς containers χωρίς χειροκίνητες ρυθμίσεις

Πολλά από τα βήματα που θα εκτελέσεις περιέχονται στον Getting Started οδηγό, με τη διαφορά ότι το Forge αναλαμβάνει την “βρώμικη” δουλειά για εσένα. Σχεδιάσαμε αυτόν τον οδηγό ώστε να διαβάζεται γρήγορα και να εξοικειωθείς άμεσα!

Παραδοχές

Ο οδηγός αυτός προϋποθέτει ότι έχεις εγκαταστήσει το JBoss Forge. Η εγκατάσταση του Forge είναι μια σχετικά σύντομη διαδικασία. Ανάτρεξε στον οδηγό Getting Started ή στο official Forge documentation για οδηγίες λήψης και εγκατάστασης. Επίσης θα χρειαστείς το JDK 1.6 ή μεγαλύτερης έκδοσης εγκατεστημένο στο μηχάνημά σου.

Ο οδηγός αυτός προσομειώνει τα αποτελέσματα για έναν χρήστη με home directory /home/ike ο οποίος δημιουργεί projects στον φάκελο projects και βάζει τις εφαρμογές του στον φάκελο applications. Ρύθμισε αυτά τα paths ώστε να ταιριάζουν με το σύστημά σου.

Δημιουργία Project

Πριν ξεκινήσουμε με το Arquillian, πρέπει να δημιουργήσουμε ένα project. Αν δεν έχεις δημιουργήσει ήδη κάποιο, χρησιμοποίησε τις ακόλουθες Forge εντολές ώστε να δημιουργήσεις ένα πρότυπο Java EE 6 project το οποίο περιλαμβάνει CDI.

$ new-project --named arquillian-demo --topLevelPackage org.arquillian.example
? Use [/home/ike/projects/arquillian-demo] as project directory? [Y/n]
***SUCCESS*** Created project [arquillian-demo] in new working directory [/home/ike/projects/arquillian-demo]
Wrote /home/ike/projects/arquillian-demo
Wrote /home/ike/projects/arquillian-demo/pom.xml
Wrote /home/ike/projects/arquillian-demo/src/main/java
Wrote /home/ike/projects/arquillian-demo/src/test/java
Wrote /home/ike/projects/arquillian-demo/src/main/resources
Wrote /home/ike/projects/arquillian-demo/src/test/resources
Wrote /home/ike/projects/arquillian-demo/src/main/java/org/arquillian/example
Wrote /home/ike/projects/arquillian-demo/src/main/resources/META-INF/forge.xml

Το Forge προσθέτει το JBoss Community repository στο pom.xml αρχείο. Ωστόσο, το repository αυτό δεν είναι απαραίτητο για την χρήση του Arquillian. Μπορείς εύκολα να το αφαιρέσεις από το pom.xml αρχείο χρησιμοποιώντας την Forge εντολή:

$ project remove-repository http://repository.jboss.org/nexus/content/groups/public 
Removed repository [JBOSS_NEXUS->http://repository.jboss.org/nexus/content/groups/public]
Wrote /home/ike/projects/arquillian-demo/pom.xml

Μόλις δημιούργησες ένα νέο project! Στη συνέχεια θα χρειαστεί να προσθέσουμε κώδικα για να τεστάρουμε. Ας δούμε πως μπορούμε να χρησιμοποιήσουμε το Forge για να δημιουργήσουμε ένα νέο CDI bean.

Αρχικά, θα εγκαταστήσουμε το CDI στο project μας χρησιμοποιώντας το beans plugin.

$ beans setup
***SUCCESS*** Installed [forge.spec.cdi] successfully.
***SUCCESS*** Beans (CDI) is installed.
Wrote /home/ike/projects/arquillian-demo/src/main/resources/META-INF/beans.xml
Wrote /home/ike/projects/arquillian-demo/pom.xml

Έπειτα θα χρησιμοποιήσουμε το plugin για να δημιουργήσουμε ένα νέο dependent-scoped bean.

$ beans new-bean --type org.arquillian.example.MySimpleBean --scoped DEPENDENT
Picked up type <JavaResource>: org.arquillian.example.MySimpleBean
Wrote /home/ike/projects/arquillian-demo/src/main/java/org/arquillian/example/MySimpleBean.java

Το project έχει τώρα ένα component. Επέστρεψε στον root φακελο του project για να το τεστάρεις.

$ cd ~~

Εγκατάσταση Arquillian

Η εγκατάσταση του Arquillian είναι εύκολη όπως ίσως θα έχεις δει στον οδηγό Getting Started. Ωστόσο, χρειάζεται αρκετό copy/paste για την παραμετροποίηση ενός Arquillian container adapter στο pom.xml. Το Forge μπορεί να το κάνει αυτό για εσένα με μια εντολή!

Πρώτα χρειάζεται να εγκαταστήσεις το Forge Arquillian plugin.

$ forge install-plugin arquillian
Connecting to remote repository [https://raw.github.com/forge/plugin-repository/master/repository.yaml]... connected!
***INFO*** Preparing to install plugin: arquillian
***INFO*** Checking out plugin source files to [/tmp/forgetemp7898368163271511889/repo] via 'git'
...
***INFO*** Installing plugin artifact.
...
***SUCCESS*** Installed from [https://github.com/forge/plugin-arquillian.git] successfully.
...

Το plugin είναι έτοιμο για χρήση. Τώρα πρέπει να παραμετροποιήσουμε το Arquillian και έναν container adapter. Θα ρυθμίσουμε το Arquillian για χρήση με τον JBoss AS 7.

$ arquillian setup --container JBOSS_AS_MANAGED_7.X

Το Forge θα σου ζητήσει να ορίσεις ποια έκδοση του JUnit, Arquillian και JBoss AS 7 να χρησιμοποιήσει. Χρησιμοποίησε τις τελευταίες εκδόσεις για καθένα από τα παραπάνω.

Το Forge μπορεί ακόμη και να κατεβάσει τον JBoss AS 7 αυτόματα, κάτι το οποίο ρωτάει κατά την εγκατάσταση:

 ? Do you want Arquillian to install the container? [y/N]
Αν απαντήσεις y:
Το Forge θα σε ρωτήσει που θέλεις να εγκαταστήσεις τον JBoss AS 7 (e.g., /home/ike/applications). Στη συνέχεια το Forge ρυθμίζει το Maven dependency plugin ώστε να κατεβάσει και να αποσυμπιέσει τα περιεχόμενα του AS 7 σε αυτήν την τοποθεσία (αν δεν βρίσκονται ήδη εκεί) πριν τα tests εκτελεστούν.
Αν απαντήσεις N:
Θα χρειαστείς μια υπάρχουσα εγκατάσταση του JBoss AS 7 στο μηχάνημα σου.

Σε κάθε περίπτωση, πρέπει να γνωρίζει το Arquillian που βρίσκονται τα αρχεία εγκατάστασης του JBoss AS 7. Ένας τρόπος να γίνει αυτό είναι να ορίσεις την JBOSS_HOME environment μεταβλητή ώστε να δείχνει στο φάκελο εγκατάστασης του AS 7. Ο προτιμότερος τρόπος είναι να ορίσεις το installation path ρητά χρησιμοποιώντας το jbossHome container configuration property στο arquillian.xml αρχείο. Το Forge μπορεί να βοηθήσει με αυτό ως εξής:

$ arquillian configure-container --profile JBOSS_AS_MANAGED_7.X
Which property do you want to set?

  1 - [Configuration{type='java.lang.String', name='jbossHome', description='The JBoss configuration to start.', defaultValue='$JBOSS_HOME'}]
  ...
 ? Choose an option by typing the number of the selection: 1
 ? What value do you want to set? /home/ike/applications/jboss-as-7.1.1.Final
Wrote /home/ike/projects/arquillian-demo/src/test/resources/arquillian.xml

Αυτό είναι το arquillian.xml αρχείο που προκύπτει (μορφοποιημένο για λόγους ευκρίνειας):

src/test/resources/arquillian.xml
<arquillian xmlns="http://jboss.org/schema/arquillian"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://jboss.org/schema/arquillian
        http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
    <container qualifier="JBOSS_AS_MANAGED_7.X">
        <configuration>
            <property name="jbossHome">/home/ike/applications/jboss-as-7.1.1.Final</property>
        </configuration>
    </container>
</arquillian>

Για να χρησιμοποιήσεις αυτό το container configuration, πρέπει είτε να:

  • Προσθέσεις το attribute default="true" στο <container> element μέσα στο arquillian.xml
  • Γράψεις τον qualifier JBOSS_AS_MANAGED_7.X σαν το μόνο περιεχόμενο του αρχείου src/test/resources/arquillian.launch

Αυτό ήταν! Το Arquillian είναι έτοιμο να εκτελέσει tests στον JBoss AS 7.

Γράψε ένα Test

Ας γράψουμε ένα test. Και εδώ το Forge μπορεί να μας εξοικονομήσει χρόνο.

$ arquillian create-test --class org.arquillian.example.MySimpleBean.java
Picked up type <JavaResource>: org.arquillian.example.MySimpleBeanTest
Wrote /home/ike/projects/arquillian-demo/src/test/java/org/arquillian/example/MySimpleBeanTest.java

Μια νέα test class με deployment και test μέθοδο προστέθηκε στο project.

src/test/java/org/arquillian/example/MySimpleBeanTest.java
package org.arquillian.example;

import org.arquillian.example.MySimpleBean;
import javax.inject.Inject;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
import static org.hamcrest.core.Is.*;

@RunWith(Arquillian.class)
public class MySimpleBeanTest {
    @Inject private MySimpleBean mysimplebean;

    @Deployment public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class, "test.jar")
            .addClass(MySimpleBean.class)
            .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Test
    public void testIsDeployed() {
        Assert.assertNotNull(mysimplebean);
    }
}

Όπως βλέπεις, το test ενσωματώνει την class που θα τεσταριστεί (MySimpleBean) χρησιμοποιώντας CDI. Αυτό αποδεικνύει αν το test εκτελείται μέσα στον container.

Μπορείς να εκτελέσεις το test μέσα από το IDE ή με χρήση του Maven (έξω από το περιβάλλον του Forge) ή από την console του Forge. Ας δοκιμάσουμε από την console του Forge.

$ build test --profile JBOSS_AS_MANAGED_7.X
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.arquillian.example.MySimpleBeanTest
...
Results :

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

Συγχαρητήρια! Κέρδισες την πρώτη green bar με το Arquillian και το JBoss Forge!

Τώρα ας δοκιμάσουμε να τεστάρουμε JPA κώδικα.

Test Persistence

Πριν ξεκινήσουμε να γράφουμε tests που χρησιμοποιούν το Java Persistence API (JPA), πρέπει να ρυθμίσουμε το JPA. Στη συνέχεια θα δημιουργήσουμε μια Οντότητα/Entity και το αντίστοιχο Data Access Object. Αυτές είναι οι classes που θα τεστάρουμε.

$ persistence setup --provider HIBERNATE --container JBOSS_AS7
***SUCCESS*** Installed [forge.spec.jpa] successfully.
***INFO*** Setting transaction-type="JTA"
***INFO*** Using example data source [java:jboss/datasources/ExampleDS]
 ? The JPA provider [HIBERNATE], also supplies extended APIs. Install these as well? [y/N] n
Wrote /home/ike/projects/arquillian-demo/src/main/resources/META-INF/persistence.xml
Wrote /home/ike/projects/arquillian-demo/pom.xml

Ας δημιουργήσουμε την οντότητα/entity.

$ entity --named Language --package org.arquillian.example.domain
Created @Entity [org.arquillian.example.domain.Language]
Picked up type <JavaResource>: org.arquillian.example.domain.Language
Wrote /home/ike/projects/arquillian-demo/src/main/java/org/arquillian/example/domain/Language.java

Έπειτα ας προσθέσουμε μερικά fields στην οντότητα/entity.

$ field string --named name
Added field to org.arquillian.example.domain.Language: @Column private String name;
Wrote /home/ike/projects/arquillian-demo/src/main/java/org/arquillian/example/domain/Language.java

Αν ανοίξεις την Language class, θα δεις μια πρότυπη JPA entity δομή.

Τώρα χρειάζεται να προσθέσουμε ένα Data Access Object (DAO) που να διαχειρίζεται αυτήν την οντότητα/entity. Αντίγραψε την παρακάτω dao class μέσα στο project.

src/main/java/org/arquillian/example/dao/LanguageDao.java
package org.arquillian.example.dao;

import org.arquillian.example.domain.Language;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

@Singleton
@Startup
public class LanguageDao {
    @PersistenceContext
    EntityManager em;

    public List<Language> listLanguages() {
        return em.createQuery("select l from Language l").getResultList();
    }

    @PostConstruct
    public void insertTestData() {
        Language java = new Language();
        java.setName("Java");
        em.persist(java);

        Language ruby = new Language();
        ruby.setName("Ruby");
        em.persist(ruby);

        Language groovy = new Language();
        groovy.setName("Groovy");
        em.persist(groovy);
    }
}

Για να γίνει compile αυτή η class, θα χρειαστεί να προσθέσεις τα EJB APIs στο project.

$ ejb setup
***SUCCESS*** Installed [forge.spec.ejb] successfully.
***SUCCESS*** Enterprise Java Beans (EJB) is installed.
Wrote /home/ike/projects/arquillian-demo/pom.xml

Έφτασε η στιγμή να δημιουργήσουμε την test class. Το κομμάτι αυτό μοιάζει με το πρώτο μισό του tutorial, εκτός από το ότι τώρα καθοδηγούμε την create-test εντολή να προετοιμάσει το test για να τεστάσουμε το JPA.

$ arquillian create-test --class org.arquillian.example.dao.LanguageDao.java --enableJPA
Picked up type <JavaResource>: org.arquillian.example.dao.LanguageDaoTest
Wrote /home/ike/projects/arquillian-demo/src/test/java/org/arquillian/example/dao/LanguageDaoTest.java

Αυτό πάλι δημιουργεί ένα νέο test, αλλά επίσης προσθέτει το persistence.xml στο deployment. Εδώ είναι το test που δημιουργήθηκε:

src/test/java/org/arquillian/example/dao/LanguageDaoTest.java
package org.arquillian.example.dao;

import org.arquillian.example.dao.LanguageDao;
import javax.inject.Inject;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
import static org.hamcrest.core.Is.*;

@RunWith(Arquillian.class)
public class LanguageDaoTest {
    @Inject private LanguageDao languagedao;

    @Deployment public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class, "test.jar")
            .addClass(LanguageDao.class)
            .addAsManifestResource("META-INF/persistence.xml", "persistence.xml")
            .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Test
    public void testIsDeployed() {
        Assert.assertNotNull(languagedao);
    }
}

Άνοιξε το test στο IDE και πρόσθεσε το Language entity στο deployment. Πρόσθεσε το σωστό import και έπειτα αντικατέστησε αυτή τη γραμμή:

.addClass(LanguageDao.class)

…με αυτή:

.addClasses(Language.class, LanguageDao.class)

Τώρα φτιάξε μια νέα test μέθοδο που επιβεβαιώνει την ορθή λειτουργία της listLanguages().

src/test/java/org/arquillian/example/dao/LanguageDaoTest.java
@Test
public void testListLanguages() {
    Assert.assertEquals(3, languagedao.listLanguages().size());
}

Εκτέλεσε τα tests.

$ build test --profile JBOSS_AS_MANAGED_7.X

Συγχαρητήρια! Άλλη μια green bar με το Arquillian!

Πρόσθεσε περισσότερους Container Adapters

Η προσθήκη περισσότερων container adapters είναι τόσο εύκολη όσο η εκτέλεση της setup εντολής. Για παράδειγμα, ας προσθέσουμε έναν Glassfish remote adapter.

$ arquillian setup --container GLASSFISH_REMOTE_3_1_(REST)

Η εναλλαγή μεταξύ των containers γίνεται με την επιλογή του αντίστοιχου Maven profile. Για παράδειγμα με τη χρήση Forge:

$ build test --profile GLASSFISH_REMOTE_3_1_(REST)

Μερικά πρόσθετα βήματα απαιτούνται για να τρέξει αυτό το test σε ένα GlassFish instance. Το αφήνουμε για άσκηση ~:)

Εξαγωγή του Deployment Archive

Για λόγους εκσφαλμάτωσης, μπορεί να είναι χρήσιμη η εξαγωγή του deployment archive σε ένα αρχείο. Μπορείς να το κάνεις χρησιμοποιώντας το Forge.

Αρχικά μετακινήσου σε ένα Arquillian τέστ:

$ cd src/test/java/org/arquillian/example/MySimpleBeanTest.java

Στη συνέχεια εξήγαγε το deployment archive:

$ arquillian export

Μπορείς να βρεις το deployment archive μέσα στον target φάκελο.

$ cd ~~
$ ls target/*.jar
arquillian-demo.jar

Αν ανοίξεις το jar αρχείο χρησιμοποιώντας ένα archive πρόγραμμα, θα δεις ότι ταιριάζει με το ShrinkWrap archive που όρισες στην @Deployment μέθοδο του τέστ.

Share the Knowledge

Find this guide useful?

There’s a lot more about Arquillian to cover. If you’re ready to learn more, check out the other available guides.

Feedback

Find a bug in the guide? Something missing? You can fix it by forking this website, making the correction and sending a pull request. If you’re just plain stuck, feel free to ask a question in the user discussion forum.

Recent Changelog

  • Apr 28, 2013: Accent & rephrase fixes on greek "get started faster with forge" guide by tolis-e
  • Apr 27, 2013: Add greek "get started faster with forge" guide by tolis-e

See full history »