Testing while coding is always a good practice - You can keep an eye on what is not working and find regressions while adding value with new code. This becomes even more important as your team grows and your Nuxeo Studio projects become more complex. Thanks to Nuxeo Studio’s Branch Management and Nuxeo CLI, you can build more imaginative code, scale your team conveniently, find bugs as you develop, and validate your Studio project.
Plug Nuxeo CLI Into Your Nuxeo Online Services (NOS) Account
Since Nuxeo CLI 1.5, you can connect your project with your NOS account and interact with it via the CLI. We’ve just started with this support and a lot more is coming in the next few weeks. But this CLI is already very useful, so keep reading!
First, let’s connect them together. Using your favorite terminal emulator, go to the root folder of your project (or create a new one) and run:
$ nuxeo studio
You’ll be prompted for your NOS credentials and your project’s symbolic name. (Don’t worry, we do not store them. We just use tokens afterwards.)
Run nuxeo studio
as follows:
$ nuxeo studio
info You are going to link a Studio project to this project.q
? NOS Username: akervern
? NOS Password: ********
? Studio Project: akervern-SANDBOX
After providing your credentials and Studio project your Maven dependencies tree will be updated. How you answer the last question will depend on your Maven’s global settings file. Studio Maven’s repository is protected and you must be authorized to download your artifacts and have access to the Internet. Nuxeo CLI will add your NOS Credentials to nuxeo-studio
server if they are not already registered. And I insist: you MUST read and follow Maven’s Password Encryption Guide before going further; having your password in clear text is…BAD.
If you are afraid when it asks if you want to override your settings.xml
file, check this out:
conflict ../../../../.m2/settings.xml
? Overwrite ../../../../.m2/settings.xml? (Ynaxdh)
y) overwrite
n) do not overwrite
a) overwrite this and all others
x) abort
d) show the differences between the old and the new
h) Help, list all options
Answer:
I recommend you show the differences (d
) first, in order to ensure that the modified lines are correct. Then, if everything looks ok, you can overwrite (y
) with the changes.
Create a Simple Scripting Operation
Next, let’s create a simple Automation Script in our Studio Project. Open Nuxeo Studio, and create an Automation Scripting Operation called smartest_thing
using void
as both input and output.
The content is trivial:
function run(input, params) {
return 5;
}
Don’t forget to save this operation. The next step will certainly be more interesting.
Unit Tests in Studio
Let’s assume that you have some basic knowledge about Nuxeo testing and have read a few lines about our Junit based Unit Test Framework. Also, if you’ve already read my documentation on How to Test a Studio Bundle, you are ready to go, and have my gratitude for reading it through!
We are going to use our new annotation PartialDeploy
(available since 9.1
or 8.10-HF04
), that lets you select exactly which contributions you want to deploy during your test regardless of the requirements. It comes with some pre-filled classes to help you deploy most of what you can configure in Studio:
org.nuxeo.runtime.test.runner.TargetExtensions.ContentModel
: Deploys Schemas, Document Types, Life Cycle, Directories and Versions Policy. -org.nuxeo.runtime.test.runner.TargetExtensions.ContentTemplate
: Deploys everything fromContentModel
and Content Templates. -org.nuxeo.runtime.test.runner.TargetExtensions.Automation
: Deploys everything fromContentModel
, Automation Chain and Automation Scripting.
Test an Automation Scripting Operation
First, let’s bootstrap an empty test:
$ nuxeo bootstrap test-empty
info Installation of single-module is skipped.
info You'll be prompted for generation of:
info blog-project-core: test-empty
create Generate Module: blog-project-core
create Generating Test empty
info Parameters: Unit test package, Unit test class name, Using feature
? Unit-Test package: org.nuxeo.sample
? Unit-Test class name: MySmartestOperation
? Using Feature: AutomationFeature
info Maven dependency: org.nuxeo.runtime:nuxeo-runtime-test:::test
info Maven dependency: org.nuxeo.ecm.platform:nuxeo-platform-test:::test
info Maven dependency: org.nuxeo.ecm.platform:nuxeo-platform-audit-core::test-jar:test
info Maven dependency: org.nuxeo.ecm.automation:nuxeo-automation-test:::test
force pom.xml
create src/test/java/org/nuxeo/sample/MySmartestOperation.java
info You can start editing code or you can continue with calling another generator (nuxeo bootstrap [<generator>..])
Using your preferred IDE, open the unit test class MySmartestOperation
. Now we are going to align the test to make sure that our operation is correctly returning 5
.
Note that if you want to test something more ‘real’, don’t forget to deploy the actual project bundle as well.
package org.nuxeo.sample;
import static org.junit.Assert.assertEquals;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.nuxeo.ecm.automation.AutomationService;
import org.nuxeo.ecm.automation.OperationContext;
import org.nuxeo.ecm.automation.OperationException;
import org.nuxeo.ecm.automation.test.AutomationFeature;
import org.nuxeo.ecm.core.test.DefaultRepositoryInit;
import org.nuxeo.ecm.core.test.annotations.Granularity;
import org.nuxeo.ecm.core.test.annotations.RepositoryConfig;
import org.nuxeo.runtime.test.runner.Features;
import org.nuxeo.runtime.test.runner.FeaturesRunner;
import org.nuxeo.runtime.test.runner.PartialDeploy;
import org.nuxeo.runtime.test.runner.TargetExtensions;
/**
* Empty Unit Testing class.
* <p/>
*
* @see <a href="https://doc.nuxeo.com/corg/unit-testing/">Unit Testing</a>
*/
@RunWith(FeaturesRunner.class)
@Features(AutomationFeature.class)
@RepositoryConfig(init = DefaultRepositoryInit.class, cleanup = Granularity.METHOD)
// !! Notice your Project symbolic name is prefixed with "studio.extension."
@PartialDeploy(bundle = "studio.extensions.akervern-SANDBOX", extensions = TargetExtensions.Automation.class)
public class MySmartestOperation {
@Inject
protected AutomationService automationService;
@Test
public void assertWeAreSmart() throws OperationException {
// !! Notice the Scripting name is prefixed with "javascript."
Object res = automationService.run(new OperationContext(), "javascript.smartest_thing");
assertEquals(5, res);
}
}
And voila! You just wrote your first unit test validating the behavior of your Automation Scripting Operation. Welcome to TDD!
Bonus Point
If you are a part of a “Clean Deployment Aficionados” team, someone who loves to do things well, or just someone who follows best practices, you probably already have a Nuxeo Package in your project’s modules. If not, get started by running nuxeo bootstrap package
and all members of your Clean Deployment Aficionados team will love you. Then, you can build your project and open the package file, located in {your-project}-package/target/{your-project}-1.0.zip
. Take a look inside. You can see that it now contains your Studio project jar file. You are now able to install your custom Java bundles and the Studio project together. Less deployment complexity means more time to enjoy adult BEvERages…or soda!