Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Backend (Java / REST) Code Tests

Overview of Test Framework

Technologies used

...

These three modules encompass most of the current test framework:

  • Parent module (pom.xml): This POM builds our testEnvironment.zip (see "generate-test-env" profile). This test environment consists of a dspace install folder (including all configs and required subdirectories). It is unzipped and used by all other modules for testing.  Modules can also override the default test environment configurations by adding their own "/test/data/dspaceFolder"
  • dspace-api (Java API): This layer has some basic unit & integration tests for the Java API / DAOs.  (Unfortunately, at this time, this module does not have as many tests as it could/should)
  • dspace-server-webapp (Server Webapp / REST API): This layer is primarily integration tests for the REST API and other web interfaces (SWORD, OAI-PMH, etc).Two types of integration tests existAbstractControllerIntegrationTest : This style of Integration Test is for testing any class which is an @Controller (which is the majority of classes in the Server Webapp).  This type of integration test uses Spring's built in caching and MockMVC to speed up the integration tests.
  • AbstractWebClientIntegrationTest: This style of Integration Test is for testing classes which require a full webserver to run. As such, it will run slower, and is primarily used for non-REST API classes, such as testing SWORD or OAI-PMH. Those each require a full webserver to be started, as they are not Spring Controllers (and are not built on Spring Boot).

Checklist for building good tests

  •  Integration Tests must be written for any methods/classes which require database access to test.  We feel integration tests are more important than unit tests (and you'll see this in our codebase).
  •  Unit Tests must be written for any (public or private) methods/classes which don't require database-level access to test.  For example, a utility method that parses a string should have a unit test that proves the string parsing works as expected.
  •  Include tests for different user types to prove access permissions are working. This includes testing as (1) an Anonymous user, (2) an Authenticated User (non-Admin), (3) an Administrator and/or Community/Collection Admin (as necessary).
  •  Include tests for known error scenarios & error codes.  If the code throws an exception or returns an 4xx response, then a test should prove that is working.
  •  Bug fix PRs should include a test that reproduces the bug to prove it is fixed.  For clarity, it may be useful to provide the test in a separate commit from the bug fix.
  •  Every test method must cleanup any test data createdSee guidelines below for "Cleaning up test data".
  •  Use "context.turnOffAuthorisationSystem()" sparingly, and always follow-up  with a "context.restoreAuthSystemState()" as soon as possible (and in the same test method).  As turning off the authorization system can affect the behavior of tests, only use these methods when you need to create or delete test data.

Writing Integration Tests

A few quick guidelines on writing DSpace Integration Tests

  • All integration test classes must end in "IT". For example: "ItemRestRepositoryIT.java" or "StructBuilderIT.java"
  • All integration test classes should extend one of the Abstract classes provided.  These include:
    • For dspace-server-webapp, two Abstract classes exist, based on the type of integration test
      • org.dspace.app.rest.test.AbstractControllerIntegrationTest : This style of Integration Test is for testing any class which is an @Controller (which is the majority of classes in the REST API / Server Webapp).  This type of integration test uses Spring's built in caching and MockMVC to speed up the integration tests.  One example is the ItemRestRepositoryIT (which tests the "/api/core/items" endpoints in the REST API).
      • org.dspace.app.rest.test.AbstractWebClientIntegrationTest: This style of Integration Test is for testing classes which require a full webserver to run. As such, it will run slower, and is primarily used for non-REST API classes, such as testing SWORD or OAI-PMH. Those each require a full webserver to be started, as they are not Spring Controllers (and are not built on Spring Boot).  One example is OAIpmhIT (which tests the dspace-oai module)
    • For dspace-api, all Integration Tests should extend org.dspace.AbstractIntegrationTest
  • As Integration Tests generate a lot of test data, all Integration tests must be sure to follow our guidelines for "Cleaning up test data" (see below).
  • Many example Integration Tests can be found in the dspace-server-webapp (see org.dspace.app.rest.*) and dspace-api modules.  We recommend looking at them for example code, etc.

Writing Unit Tests

A few quick guidelines on writing DSpace Unit Tests

  • All unit test classes must end in "Test". For example: "ItemTest.java" or "DiscoverQueryBuilderTest"
  • For dspace-api, all Unit Tests should extend either AbstractUnitTest or AbstractObjectTest.  For example, see ItemTest
  • For dspace-server-webapp, Unit Tests need not extend any class and just need to be named ending with Test.  For example, see DiscoverQueryBuilderTest
  • Many example Unit Tests can be found in the dspace-api, and a few in the dspace-server-webapp.  We recommend looking at them for example code, etc.

Cleaning up test data

Integration Tests necessarily have to create test data to verify the code they are testing is working properly.  But, just as importantly, they must cleanup any test data they create.  Integration tests which do not cleanup after themselves often result in odd Travis CI failures. These odd failures in Travis CI may occur anytime Travis CI runs tests in a different order than your local machine and test data from an earlier test directly affects the results of a later test.

...