diff --git a/docs/imgs/sdk-it-eclipse-results.png b/docs/imgs/sdk-it-eclipse-results.png new file mode 100644 index 00000000..0eeaf31a Binary files /dev/null and b/docs/imgs/sdk-it-eclipse-results.png differ diff --git a/docs/imgs/sdk-it-eclipse-run.png b/docs/imgs/sdk-it-eclipse-run.png new file mode 100644 index 00000000..69fa2d22 Binary files /dev/null and b/docs/imgs/sdk-it-eclipse-run.png differ diff --git a/docs/imgs/sdk-it-intellij-results.png b/docs/imgs/sdk-it-intellij-results.png new file mode 100644 index 00000000..5fb15165 Binary files /dev/null and b/docs/imgs/sdk-it-intellij-results.png differ diff --git a/docs/imgs/sdk-it-intellij-run.png b/docs/imgs/sdk-it-intellij-run.png new file mode 100644 index 00000000..0c9ba203 Binary files /dev/null and b/docs/imgs/sdk-it-intellij-run.png differ diff --git a/docs/integration-testing.md b/docs/integration-testing.md new file mode 100644 index 00000000..8649cfdb --- /dev/null +++ b/docs/integration-testing.md @@ -0,0 +1,32 @@ +--- +Title: Integration testing +Added: v3.0.0 +Last reviewed: 2019-01-16 +--- +# Integration testing + +"Integration testing is the phase in software testing where individual software modules are combined and tested as a group. It occurs after unit testing and +before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined +in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing. [Wikipedia]." + +Even if the definition of integration testing is a general description, the concept is also valid for Alfresco projects. + +The Alfresco SDK 4.0 keeps the same general idea of integration testing provided by SDK 3.0, but this new version reshapes it slightly to leverage on a +Docker-oriented environment. + +Here are the basics to understanding and using integration testing in the context of projects created with the SDK, from a technical perspective: +* SDK 4.0 develops integration tests for the platform only. Currently, the integration tests that the SDK is able to manage by default is related to +Alfresco Content Services (ACS) only. +* Integration tests require an ACS instance to be up and running. You will see that all the scripts and commands are designed to easily manage this +requirement, but the prerequisite for the SDK is that an ACS instance is available. +* If you're running a project created with a Platform JAR archetype, integration tests are not provided by default. However, you can copy them from your +All-In-One project. + +## How SDK's integration tests work + +If you want to know how the SDK's integration tests work and what are the basic tests included in the archetypes, then visit [How SDK's integration tests work](it-working.md). + +## How to run SDK's integration tests + +If you want to know how you can execute the SDK's integration tests in different environments and some considerations about it, then visit +[How to run SDK's integration tests](it-running.md). diff --git a/docs/it-running.md b/docs/it-running.md new file mode 100644 index 00000000..0b70804e --- /dev/null +++ b/docs/it-running.md @@ -0,0 +1,116 @@ +--- +Title: How to run SDK's integration tests +Added: v3.0.0 +Last reviewed: 2019-01-16 +--- +# How to run SDK's integration tests + +Running the integration tests of a project generated from the Alfresco SDK 4.0 archetypes is pretty easy. Let's distinguish different cases of executing the +integration tests. + +## Command line + +If you want to run the integration tests from the command line you'll have to use the utility scripts provided by all the projects generated from the +archetypes. These are `run.sh` if you're on Unix systems or `run.bat` if you're on Windows systems. + +If you want to spin up a new dockerised environment with ACS, run the integration tests and stop that environment, you'll use the `build_test` goal: + +``` +$ ./run.sh build_test +``` + +If you want all your previous data in the docker environment to be wiped out before the execution of the integration tests, remember to call the `purge` goal +before the `build_start` goal: + +``` +$ ./run.sh purge +$ ./run.sh build_test +``` + +The `build_test` goal will execute the next list of tasks: +* Stop any previous execution of the dockerised environment. +* Compile all the source code. +* Rebuild the custom Docker images of the project. +* Start a new dockerised environment. +* Execute the integration tests. +* Show the logs of the docker containers during the tests execution. +* Stop the dockerised environment. + +If your dockerised environment is already started and you simply want to execute the integration tests against that existing ACS instance, then use the `test` +goal: + +``` +$ ./run.sh test +``` + +### Configuring a custom ACS endpoint location + +If you want to run your integration tests against an ACS instance not exposed in `http://localhost:8080/alfresco` you'll need to modify a maven property +before executing the tests. + +The maven property for the test ACS instance endpoint location is `acs.endpoint.path` and you can configure it in the `pom.xml` file in the root folder of your +project: + +``` + + ... + http://192.168.99.100:8080/alfresco + .. + +``` + +This parameter is **specially important** if you're running your dockerised environment using [Docker Toolbox](https://docs.docker.com/toolbox/) instead of +[Docker Desktop](https://www.docker.com/products/docker-desktop). If that is the case, then the Docker container exposed ports are not mapped in the hosted +machine as `localhost` but as an assigned IP address (i.e. `192.168.99.100`). + +## Eclipse IDE + +If your project is available in Eclipse, you can easily run one or more of the integration tests directly from your IDE. + +To run the integration tests: + +1. In order to properly execute the integration tests the dockerised environment must be already up and running. So, before executing the tests you must run +the `build_start` or the `start` goal of the `run` script. + +2. Open the project using the IDE. + +3. Select the classes for the integration tests (either one, some, or the whole package). + +4. Right click and select `Run As ...`, then click `JUnit Test`. + +![Alt text](./imgs/sdk-it-eclipse-run.png?raw=true "Eclipse integration tests run") + +Once the tests have completed (typically, after a few seconds), the results are presented. + +![Alt text](./imgs/sdk-it-eclipse-results.png?raw=true "Eclipse integration test execution results") + +When using an IDE, the source code related to the integration tests is the one deployed directly on the platform side. This means that an update in the code +for the Java classes will be included when you run the integration tests _if and only if_ they are deployed in the platform. To avoid stopping/starting +Alfresco Content Services with every change, use **hot reloading** as the only way to deploy the new version of the Java classes. For more details, see +[JRebel](jrebel.md) / [HotSwapAgent](hotswap-agent.md) Hot reloading. + +## IntelliJ IDEA IDE + +If your project is available in IntelliJ IDEA, you can easily run one or more of the integration tests directly from your IDE. + +To run the integration tests: + +1. In order to properly execute the integration tests the dockerised environment must be already up and running. So, before executing the tests you must run +the `build_start` or the `start` goal of the `run` script. + +2. Open the project using the IDE. + +3. Select the classes for the integration tests (either one, some, or the whole package). + +4. Right click and select `Run Tests`. + +![Alt text](./imgs/sdk-it-intellij-run.png?raw=true "IntelliJ IDEA integration tests run") + +Once the tests have completed (typically, after a few seconds), the results are presented. + +![Alt text](./imgs/sdk-it-intellij-results.png?raw=true "IntelliJ IDEA integration test execution results") + +When using an IDE, the source code related to the integration tests is the one deployed directly on the platform side. This means that an update in the code +for the Java classes will be included when you run the integration tests _if and only if_ they are deployed in the platform. To avoid stopping/starting +Alfresco Content Services with every change, use **hot reloading** as the only way to deploy the new version of the Java classes. For more details, see +[JRebel](jrebel.md) / [HotSwapAgent](hotswap-agent.md) Hot reloading. diff --git a/docs/it-working.md b/docs/it-working.md new file mode 100644 index 00000000..0a15b1eb --- /dev/null +++ b/docs/it-working.md @@ -0,0 +1,161 @@ +--- +Title: How SDK's integration tests work +Added: v3.0.0 +Last reviewed: 2019-01-16 +--- +# How SDK's integration tests work + +The Alfresco SDK's integration tests are primarily supported by a utility module included in the SDK called [Alfresco Rapid Application Development](https://github.com/Alfresco/alfresco-sdk/tree/master/modules/alfresco-rad) +(alfresco-rad). This module basically enables the execution of the integration tests within the context of a running Alfresco Content Service (ACS) instance. + +## Alfresco Rapid Application Development (Alfresco RAD) + +The Alfresco RAD is an Alfresco module which main functionality is offering the ability to execute integration tests in a real ACS context. The core classes +that conforms the Alfresco RAD module are: +* [AlfrescoTestRunner](https://github.com/Alfresco/alfresco-sdk/blob/master/modules/alfresco-rad/src/main/java/org/alfresco/rad/test/AlfrescoTestRunner.java). +A JUnit test runner that is designed to work with an ACS instance. It detects if it's executing a test inside of a running ACS instance. +If that is the case the tests are all run normally. If the test is being run from outside the repository, then, instead of running the actual test, an HTTP +request is made to a Web Script (`RunTestWebScript`) in a running Alfresco instance. +* [RunTestWebScript](https://github.com/Alfresco/alfresco-sdk/blob/master/modules/alfresco-rad/src/main/java/org/alfresco/rad/test/RunTestWebScript.java). +This Web Script works in consort with the `AlfrescoTestRunner`. When a test is run from outside the repository, the Alfresco test runner sends a proxied +request to perform the test to this script. This runs the test and wraps the results up so that the test initiator can be fooled into thinking they are +running the tests locally. +* [AbstractAlfrescoIT](https://github.com/Alfresco/alfresco-sdk/blob/master/modules/alfresco-rad/src/main/java/org/alfresco/rad/test/AbstractAlfrescoIT.java). +Abstract integration test class that gives access to the Alfresco Spring Application context and the `ServiceRegistry` that should be used when accessing +Alfresco Services. +* [Remote](https://github.com/Alfresco/alfresco-sdk/blob/master/modules/alfresco-rad/src/main/java/org/alfresco/rad/test/Remote.java). The `AlfrescoTestRunner` +class has to determine where the ACS instance endpoint is exposed to send the proxied request to the `RunTestWebScript`. It uses, in order, the next three +mechanisms: + * The `Remote` annotation. If the test is annotated with `@Remote`, then it uses the `endpoint` property to determine the ACS endpoint. + * The `acs.endpoint.path` Java system property. If the Java system property is set, then its value is used as the ACS endpoint. + * A default value. If none of the previous mechanisms returned a value, then the default value `http://localhost:8080/alfresco` is used. + +In summary, if you want to execute your integration tests inside an existing ACS instance, you'll need to annotate them with the JUnit `RunWith` annotation +and set the value to `AlfrescoTestRunner.class`. If you want to customise the default ACS endpoint location, you can either annotate your tests with `Remote` +or set the Java system property `acs.endpoint.path`. + +## Integration tests configuration in the All-In-One project + +So, taking into account the previous section, let's see how the integration tests are configured in a project generated from the SDK 4.0 All-In-One archetype. + +* The maven dependencies required to execute the integration tests are deployed to the ACS Docker image in the `PROJECT_ARTEFACTID-platform-docker` maven +module using the `maven-dependency-plugin`. The configuration is done in the file `PROJECT_ARTEFACTID-platform-docker/pom.xml`: + +``` + + org.apache.maven.plugins + maven-dependency-plugin + + + + copy-repo-extension + pre-integration-test + + copy + + + + ... + + + + org.alfresco.maven + alfresco-rad + ${alfresco.sdk.version} + false + ${project.build.directory}/extensions + + + org.alfresco + integration-tests + 1.0-SNAPSHOT + tests + false + ${project.build.directory}/extensions + + + junit + junit + 4.12 + false + ${project.build.directory}/extensions + + + org.mockito + mockito-all + 1.9.5 + false + ${project.build.directory}/extensions + + + org.apache.httpcomponents + httpclient + 4.5.2 + false + ${project.build.directory}/extensions + + + + + ... + + +``` + +* The `integration-tests` maven module include the definition of all the integration test classes to be executed against the existing ACS instance. The test +classes are included in the folder `integration-tests/src/test/java`. + +* The `integration-tests` maven `pom.xml` file adds the configuration of the `acs.endpoint.path` in case it is required. This is done using the +`maven-failsafe-plugin`: + +``` + + org.apache.maven.plugins + maven-failsafe-plugin + + + ${test.acs.endpoint.path} + + + +``` + +This is specially useful when the ACS endpoint is not exposed at the default location (`http://localhost:8080/alfresco`). This property is important when the +development environment is run using Docker Toolbox (old Windows and MacOS versions). In this case, the container exposed ports are not mapped to localhost, +but to a custom IP provided by the Virtual Box virtual machine (i.e. `http://192.168.99.100:8080/alfresco`). + +* The All-In-One project utility scripts (`run.sh` / `run.bat`) offer two different tasks to execute the integration tests: + * `build_test`. It builds the whole project, recreates the ACS and Share docker images, starts the dockerised environment, executes the integration tests + from the `integration-tests` module and stops the environment. + * `test`. It simply executes the integration tests (the environment must be already started). + +## Sample tests included in the generated project + +The All-In-One archetype includes some basic integration tests that demonstrates the way you can implement the integration tests of your custom module. This +section illustrates what they check. + +### `CustomContentModelIT`: Checking the correct existence and setup of a custom model + +This integration test verifies the existence of the `{http://www.acme.org/model/content/1.0}contentModel` in the Alfresco Content Services instance. It also +creates a new node in the repository with the following features: +* The node is named `AcmeFile.txt`. +* The node type is set to `{http://www.acme.org/model/content/1.0}document`. +* The node property `securityClassification` is set to `Company Confidential`. +* The aspect `cm:titled` is added to the new node. + +Once created, some Java assertions are raised to check the correct definition of the node. As a last task, the node is deleted from the repository to clean +the environment. + +### `DemoComponentIT`: Checking the Alfresco Content Services DemoComponent component + +This integration test verifies the existence of the `DemoComponent` component deployed in the Alfresco Content Services instance. You can find the definition +of the `DemoComponent` as a custom component of a project created with the All-In-One archetype. For more details, see the class definition in +`PROJECT_ARTEFACTID-platform-jar/src/main/java/com/example/platformsample/DemoComponent.java`. + +The integration test retrieves the `DemoComponent` bean from the Alfresco Content Services instance (see `testGetCompanyHome()`), and requests the Company +Home component. In addition, some Java assertions check if Company Home is identified correctly and has seven children stored in it. + +### `HelloWorldWebScriptIT`: Checking the Alfresco Content Services helloworld webscript + +This integration test is the simplest one, and verifies the existence and the response of the `helloworld` web script in the Alfresco Content Services instance. +The test invokes the web script at the URL `http://localhost:8080/alfresco/service/sample/helloworld` and checks the response using some Java assertions.