Versions Compared

Key

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

TBD: include pointers to "good" unit tests in the project

Geode is tested with a combination of tests written with JUnit , DUnit (distributed unit) and regression testsand DUnit. JUnit tests are written as with any other project while DUnit tests use a multi-JVM environment (see Distributed Unit Tests DistributedTest).

JUnit tests are divided into two main categories: UnitTest and IntegrationTest.

1. UnitTest: is a test with very narrow and well defined scope. Any complex dependencies and interactions are stubbed or mocked.

  • Should use JUnit 4 syntax
  • File name ends with *Test
  • Should use Category annotation of type UnitTestbe part of the test source set folder (<geode-module-dir>/test/java)
  • Should complete in milliseconds 
  • Should generally test a single class
  • Typically uses white-box testing, uses Mocks/Fakes and helps guarantee internal quality (quality of code and class design)
  • Follows "A Set of Unit Testing Rules" by Michael Feathers
    • A UnitTest should not do any of the following:
      • communicate with a database
      • communicate across the network
      • access the file system
      • prevent the running of other unit tests in parallel
      • require anything special in the environment (such as editing config files or running an external process)

2. IntegrationTest: a test involving inter-operation of components or subsystems.

  • Should use JUnit 4 syntax
  • File name ends with *IntegrationTest
  • Should use Category annotation of type IntegrationTestbe part of the integrationTest source set folder (<geode-module-dir>/integrationTest/java)
  • May take longer than a UnitTest but should generally complete in seconds
  • May test a single class or any combination of classes including end-to-end testing of Geode
  • Typically uses black-box testing but may include some white-box testing and helps guarantee external quality (feature delivers value to User)
  • An IntegrationTest may do any of the following:
    • communicate across the network
    • access the file system
    • require anything special in the environment (such as editing config files or running an external process)
    Good examples in Geode:
    • RegionExpirationIntegrationTest

DUnit tests are a special type of JUnit test involving multiple JVMs. This supports writing tests for a Geode cluster.

3. DistributedTest: a test involving multiple members of a distributed system.

  • Should use JUnit 4 syntax
  • File name ends with *DistributedTest or *DUnitTest
  • Should use Category annotation DistributedTestbe part of the distributedTest source set folder (<geode-module-dir>/distributedTest/java)
  • Should generally complete in seconds
  • May test interactions between multiple JVMs in a Geode cluster or via networking or via file system
  • Typically uses black-box testing but may include some white-box testing and helps guarantee external quality (feature delivers value to User)
  • A DistributedTest may do any of the following:
    • communicate across the network
    • access the file system
    • require anything special in the environment (such as editing config files or running an external process)

...

  • JUnit 4
  • System Rules – powerful set of JUnit 4 Rules
  • AssertJ – richer than JUnit 4 Assert and includes better support for expected exceptions
  • Awaitility – useful for awaiting asynchronous conditions
  • Mockito – preferred over all other mocking libraries
  • JUnitParams – provides test method parameterization
  • Catch-Exception – better support for expected exceptions especially with complex nesting of exceptions or exceptions with unusual APIs
  • PowerMock – use this as a last resort – refactoring code to facilitate better testing is preferred

...

  • Custom JUnit 4 Rules and testing frameworks (including DUnit) that are part of

...

  • Geode

...

  • geode-junit JUnit 4 Rules:
    • ExecutorServiceRule – provides ExecutorService for concurrent testing
    • ExpectedTimeoutRule – verifies that an API times out and potentially throws TimeoutException
    • JarFileRule – creates a Jar file in an internal TemporaryFolder containing a dynamically generated class
    • RepeatRule – repeatedly executes a test
    • RequiresGeodeHome – asserts precondition that GEODE_HOME system property is specified
    • RestoreLocaleRule – restores JVM to original Locale
    • RestoreTCCLRule – restores Thread Context Class Loader
    • RetryRule – retries a test until it passes or exceeds specified number of retries
    • TemporaryFileRule – destroys specified files or directories that aren't created in a TemporaryFolder
    • UseJacksonForJsonPathRule – specifies that JsonPath should use Jackson instead of its default JSON library
    • GfshRule – allows use of Gfsh script string to fork a JVM process in an IntegrationTest
  • geode-junit JUnit 4 Rules that extend commonly used JUnit 4 Rules:
    • SerializableTemporaryFolder – allows a TemporaryFolder to be shared across multiple JVMs in a DistributedTest
    • SerializableTestName – allows a TestName to be shared across multiple JVMs in a DistributedTest
  • geode-core (under test) old TestCase classes for DistributedTest:
    • DistributedTestCase – base class for pre-existing distributed tests
    • CacheTestCase – base class for pre-existing distributed tests with APIs for getCache
  • geode-core (under test) API classes for DistributedTest:
    • AsyncInvocation – performs asynchronous invocations in multiple JVMs with Future API
    • Disconnect – disconnects JVMs from Geode cluster
    • DistributedTestUtils – misc utility APIs that don't fit into any of the other DistributedTest API classes
    • DUnitBlackboard – provides a blackboard (distributed map) that can be used in multiple JVMs
    • IgnoredException – specifies Exception string that will be ignored during suspect string grep which occurs in tearDown of DistributedTests
    • Invoke – APIs to invoke SerializableRunnables and SerializableCallables in multiple JVMs
    • NetworkUtils – networking utility APIs to get IP or host name
    • ThreadUtils – utility APIs to dumpt thread stacks
    • VM – the API representation of a remote JVM which is fetched from Host class
  • geode-core (under test) JUnit 4 Rules for DistributedTest:
  • DistributedRule – use this instead of extending DistributedTestCase
  • CacheRule – use this with DistributedRule instead of extending CacheTestCase
  • ClusterStartupRule – use this by itself for Gfsh and Management tests
  • DistributedDisconnectRule – disconnects all JVMs from Geode cluster (similar to APIs in Disconnect class)
  • DistributedRestoreSystemProperites – version of RestoreSystemProperites which executes in all JVMs
  • DistributedUseJacksonForJson – version of UseJacksonForJsonPathRule which executes in all JVMs
  • SharedCountersRule – provides distributed counters and APIs which can be used in all JVMs
  • SharedErrorCollector – version of ErrorCollector which can be used in all JVMs

Always write unit tests for new functionality and always ensure that all unit tests pass before submitting a pull request. Try to make sure new functionality is covered by unit tests, whether or not there are also integration tests as well.

...