Tuxitecte

mercredi 21 avril 2010

Maven + Alfresco : Unit Test



Hello world!

In this post, I'll try to share my approach to unit tests with Maven during AMP creation.
Of course if I say TEST, I say CODE! So prepare your eclipse !


Objectives
:
As a developer and integrator my goal is multiple :
  • First of all I want to run unit tests in Eclipse. I want to keep the debugger. It helps me a lot during coding!
  • Then I want to run all my unit tests via Maven. So when I want to create a version of my AMP, it has to pass all tests! I think it's a good practice (^^)

So how?
If you followed my 2 previous posts here and here, we have in our possession two AMP (well. .. 2 projects MAVEN to be exact ...).

  • First, alf-sdk. It is a kind of PARENT-AMP which contains all dependencies of Alfresco SDK and all plugins to create an AMP.
  • Second, alf-amp-osecm. This is our AMP. It inherit alf-sdk.

We will modify these 2 projects to implement unit tests.

1. Updating ALF-SDK

First we will put some news in our parent pom. The main changes occur at build tag.

  • Maven-compiler-plugin and maven-resources-plugin. They received parameters for encoding.
  • Maven-eclipse-plugin has been installed. We will see in the next paragraph why ...





4.0.0
fr.opensourceecm
alf-sdk
pom
3.3C
Maven - Alfresco SDK 3.3C
Super POM Maven Alfresco SDK 3.3C



....





true
src/main/resources

**README-*



true
src/main/config
alfresco/module/${groupId}.${artifactId}

**README-*







org.apache.maven.plugins
maven-eclipse-plugin
2.8


org.springframework.ide.eclipse.core.springnature


org.springframework.ide.eclipse.core.springbuilder





org.apache.maven.plugins
maven-resources-plugin
2.2

UTF-8




org.apache.maven.plugins
maven-compiler-plugin

1.6
1.6
UTF-8
true




org.alfresco.maven.plugin
maven-amp-plugin
3.0.2
true


false

alfresco/extension/**,alfresco/module/**







Once modified, you can install and deploy the artifact locally with a simple command maven :

mvn clean install


In our repository, we now have access to the module fr.opensourceecm:alf-sdk:pom:3.3C
Projects inheriting from this artifact will automatically receive the updates.


2. Updating our AMP

Now we'll create an Alfresco action and a test. As reminder, an action is a unit of work on Alfresco Repository. It can be run via a rule or directly by the user via Alfresco Explorer.
  • In our case, the action simply performs the creation of a sub-space.
  • The test class will start a background Alfresco (creation of a store), create a space, launch the action on this space and check the creation of one new sub-space.
2.1 Adding an action Alfresco
In the directory /alf-amp-osecm/src/main/java/fr/opensourceecm/alf/amp/osecm/actions / I add the action: sampleActionExecuter.java


package fr.opensourceecm.alf.amp.osecm.actions;

import java.util.List;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;

public class sampleActionExecuter extends ActionExecuterAbstractBase{

private FileFolderService fileFolderService;

private final String FOLDER_TEST_NAME = "FolderTest";

@Override
protected void executeImpl(Action arg0, NodeRef actionUponRef) {
List listNodeRef = fileFolderService.listFolders(actionUponRef);
fileFolderService.create(actionUponRef, FOLDER_TEST_NAME + "_" + listNodeRef.size(), ContentModel.TYPE_FOLDER);
}

@Override
protected void addParameterDefinitions(List arg0) {
// TODO Auto-generated method stub

}

public void setFileFolderService(FileFolderService fileFolderService) {
this.fileFolderService = fileFolderService;
}
}


Note : To create our subspace, we use the FileFolderService and the name of our space will be the concatenation between FolderTest and number of folder present.

2.2 Adding a unit test
In the directory /alf-amp-osecm/src/test/java/fr/opensourceecm/alf/amp/osecm/actions, I add the test: sampleActionExecuterTest.java


package fr.opensourceecm.alf.amp.osecm.actions;

import junit.framework.Assert;

import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.BaseAlfrescoTestCase;
import org.junit.Test;

public class sampleActionExecuterTest extends BaseAlfrescoTestCase {

protected NodeRef companyHomeRef;
protected NodeRef rootFolderTestRef;
protected final String rootFolderTestName = "ROOTFOLDERTEST";

@Test
public void testIntegrerFluxCreationParAction() throws Throwable {

// Création d'un répertoire de test dans le store de test.
rootFolderTestRef = serviceRegistry.getNodeService().createNode(
rootNodeRef, ContentModel.ASSOC_CHILDREN,
ContentModel.TYPE_FOLDER, ContentModel.TYPE_FOLDER).getChildRef();

//Lancement de l'action de création d'un sous-répertoire.
Action action = serviceRegistry.getActionService().createAction("createFolderTest-action");
serviceRegistry.getActionService().executeAction(action,rootFolderTestRef);

//Vérification de la présence du sous-répertoire.
Assert.assertEquals("ERREUR LORS DE LA RECHERCHE", 1, serviceRegistry.getNodeService().getChildAssocs(rootFolderTestRef).size());
}
}


Here I draw your attention to the inheritance. sampleActionExecuterTest extends the class BaseAlfrescoTestCase. It's a util class which allow to start a spring/alfresco context. In my class, I just create a test to start my work and verify the result.

2.3 Configuring the pom.xml
Our pom.xml will of course changed after this integration of Java code. In fact, Maven must know dependencies needed to compile classes. In this sample, we need
  • Alfresco-repository-3.3 for Alfresco services
  • Org.springframework.beans-3.0.0 to create Spring context
  • Junit for unit testing.
Our pom.xml becomes:




fr.opensourceecm
alf-sdk
3.3C

4.0.0
alf-amp-osecm
jar
0.0.3
Alfresco AMP Open Source ECM
Open Source ECM - Extension



org.alfresco.sdk
alfresco-repository-3.3
3.3
community
provided


org.alfresco.sdk
org.springframework.beans-3.0.0
3.3
community
provided


junit
junit
4.7
test





IMPORTANT NOTE: The packaging is JAR! Don't put it into AMP (it's a little "trick" to configure the project in Eclipse ...)

2.4 Configuring the Eclipse workspace
Generally (and if you've followed instructions above) you have never opened Eclipse for the previous manipulations! I agree ... is difficult. But you have to know that a Maven project generated is not directly integratable in Eclipse! In fact it is not planned for! There is no .classpath, .project file or .settings for configuring your project in Eclipse.
But Maven has a plugin to automatically create all of these configuration files. This is the maven-eclipse-plugin defined previously in the parent pom.

To create this configuration, type a command in the root directory of the maven project :

mvn eclipse:eclipse


Automatically, maven-eclipse.xml, .project and .classpath files have been created as well as .settings directories and ExternalToolBuilders (and eventually target).

Note: For users of Spring IDE, the project will have the nature of project Spring by default.

Note: If you have already joined the project in eclipse, or if you want to delete the configuration eclipse, type the following command:

mvn eclipse:clean


2.5 Importing the project in eclipse

You can now launch an eclipse (3.5R2 Galilleo for me) and import the project into your workspace. The project now looks like the image below:



Note: If you do not have this configuration, make sure you launch the command eclipse while the packaging is JAR. Indeed, if you execute this command with amp packagin the plugin will build another tree.

2.6 (Re) Definition of spring beans

We will now modify the declaration of spring beans for each part of our AMP to improve readability. For this, we will specialize a directory : context .

So in the \alf-amp-osecm\src\main\config, create a directory context and create 3 files:
  • action-context.xml
  • model-context.xml
  • webclient-context.xml

action-context.xml











model-context.xml





alfresco/module/fr.opensourceecm.alf-amp-osecm/model/ecmModele.xml






This statement, as its name suggests will allow us to define the data model. Note that in my previous post, I replaced fr.opensourceecm.alf-amp-osecm by (groupId) and (artifactId). But here, I want Eclipse to be able to understand after a compilation. Indeed Maven is the only one capable of replacing these values! So we must declare this value ...

Note: In general, groupId and artifactId must be defined at the beginning of your project.
Note: I take advantage of refactoring to simplify the name of my data model.

Now we will create the file
webclient-context.xml





alfresco/module/fr.opensourceecm.alf-amp-osecm/ui/ecm-web-client-config.xml







This statement, as its name suggests will allow us to define the configuration of the web client.
Note: I take advantage of refactoring to simplify the name of my web client config.


In the \alf-amp-osecm\src\main\config, edit the file:
module-context.xml









This file will serve to reference all statements necessary for our Spring module. In our case, to summarize, our module have : a data model, an action and a web client configuration.

2.7 Definition of our test environment
Now we will define and configure our Alfresco repository. Ie we will define the configuration settings of the database and where we put our folder (content-store and lucene indexes).

For this purpose in the directory /alf-amp-osecm/src/test/resources/alfresco/extension/ (create the missing directories if necessary) create the file

dev.properties

dir.root=./alf_data
index.recovery.mode=AUTO
integrity.failOnError=true
db.name=alf33Test
db.username=alfresco33
db.password=alfresco
db.host=localhost
db.port=3306
db.driver=org.gjt.mm.mysql.Driver
db.url=jdbc:mysql://${db.host}:${db.port}/${db.name}
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect


This file defines all properties of our test environment. In my case, I already installed and configured a MySQL database.

For more information on how to configure an environment, please download the following pdf: Manual Configuration and Installation of Alfresco 3.3

Then in the same directory, you must create the file
dev-context.xml






classpath:alfresco/repository.properties
classpath:alfresco/domain/transaction.properties


classpath*:alfresco/module/*/alfresco-global.properties

classpath*:alfresco-global.properties
classpath:alfresco/extension/dev.properties



SYSTEM_PROPERTIES_MODE_OVERRIDE




hibernate.dialect
hibernate.query.substitutions
hibernate.jdbc.use_get_generated_keys
hibernate.default_schema







This bean will identify the properties file previously created. This is used only during maven test phase

NOTES
In this step, you can add a directory /alf-amp-osecm/src/test/resources/alfresco/desktop containing the default desktop ations Alfresco (available in the sdk). Apparently it can't have them in my environment ...

In this step, you can also add a log4j.properties file in the directory /alf-amp-osecm/src/test/resources to determine levels of logs.

2.8 Changing the pom.xml

We now have an environment ready. You just have to change the packaging tag in pom.xml to AMP.

2.9 Starting the Packaging

Now your project should look like the image below:


The project is complete, you can start packaging via the command

mvn clean install


If all goes well, you see the famous and coveted BUILD SUCCESSFULL and if you pay attention to the console, it display the results of tests like
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

If so you have your first AMP tested by Maven.

CONGRATULATIONS!

In the target directory of the project, you have packaged your AMP: alf-amp_osecm.0.0.3.amp. You can install it on your local Alfresco instance.


2.10 Starting the test via Eclipse
As I said at the beginning, I also want to use Eclipse to debug my application if necessary. I execute my JUnit test and verify the result.




Goals achieved!


That's all for today!
If you have any questions, remarks or bug / improvement to report for example, feel free to post a comment.

For this part, I wish to thank G. Tournier for his help and advice.
Without him Alfresco nodes would probably still a big mystery to me.

Stay Tuned !

PS

All sources of alf-amp-osecm can be downloaded at:
http://www.box.net/shared/374lms3ogv


All sources of alf-sdk can be downloaded at:
http://www.box.net/shared/oevx14hy8n

Digg Google Bookmarks reddit Mixx StumbleUpon Technorati Yahoo! Buzz DesignFloat Delicious BlinkList Furl

1 commentaires: on "Maven + Alfresco : Unit Test"

klebeer a dit…

thanks, very helpful!!