You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2021/01/27 19:59:46 UTC

[uima-uimaj] branch UIMA-6308-Refactor-unit-tests created (now 1cfbe0c)

This is an automated email from the ASF dual-hosted git repository.

rec pushed a change to branch UIMA-6308-Refactor-unit-tests
in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git.


      at 1cfbe0c  [UIMA-6308] Refactor unit tests

This branch includes the following new commits:

     new 1cfbe0c  [UIMA-6308] Refactor unit tests

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[uima-uimaj] 01/01: [UIMA-6308] Refactor unit tests

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rec pushed a commit to branch UIMA-6308-Refactor-unit-tests
in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git

commit 1cfbe0cd459142869cdaa560d59c980cdb07f70c
Author: Richard Eckart de Castilho <re...@apache.org>
AuthorDate: Mon Jan 25 18:08:01 2021 +0100

    [UIMA-6308] Refactor unit tests
    
    - Upgraded MetaDataObject_implTest
    - Upgraded TypeSystemDescription_implTest
    - Upgrade AnalysisEngineDescription_impltTest
    - Added PrintExceptionsWhenRunFromCommandLineRule as a replacement for JUnitExtension.handleException(e) in try/catch around tests
---
 .../impl/AnalysisEngineDescription_implTest.java   | 880 ++++++++++-----------
 .../metadata/impl/MetaDataObject_implTest.java     | 362 ++++-----
 .../impl/TypeSystemDescription_implTest.java       | 296 +++----
 .../PrintExceptionsWhenRunFromCommandLineRule.java |  46 ++
 4 files changed, 777 insertions(+), 807 deletions(-)

diff --git a/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineDescription_implTest.java b/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineDescription_implTest.java
index ec06f85..8290873 100644
--- a/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineDescription_implTest.java
+++ b/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineDescription_implTest.java
@@ -16,9 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.uima.analysis_engine.impl;
 
+import static org.apache.uima.UIMAFramework.newDefaultResourceManager;
+import static org.apache.uima.resource.ResourceInitializationException.UNDEFINED_KEY_IN_FLOW;
+import static org.apache.uima.test.junit_extension.JUnitExtension.getFile;
+import static org.apache.uima.util.CasCreationUtils.createCas;
+import static org.assertj.core.api.Assertions.as;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
@@ -28,9 +35,6 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
 
-import org.junit.Assert;
-import junit.framework.TestCase;
-
 import org.apache.uima.Constants;
 import org.apache.uima.ResourceSpecifierFactory;
 import org.apache.uima.UIMAFramework;
@@ -84,580 +88,538 @@ import org.apache.uima.resource.metadata.impl.NameValuePair_impl;
 import org.apache.uima.resource.metadata.impl.TypePriorities_impl;
 import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl;
 import org.apache.uima.test.junit_extension.JUnitExtension;
-import org.apache.uima.util.CasCreationUtils;
+import org.apache.uima.test.junit_extension.PrintExceptionsWhenRunFromCommandLineRule;
 import org.apache.uima.util.InvalidXMLException;
 import org.apache.uima.util.Logger;
 import org.apache.uima.util.XMLInputSource;
 import org.apache.uima.util.XMLParser;
+import org.apache.uima.util.XMLizable;
+import org.assertj.core.api.InstanceOfAssertFactories;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.xml.sax.SAXException;
 
 /**
  * Test the AnalysisEngineDescription_impl class.
- * 
  */
-public class AnalysisEngineDescription_implTest extends TestCase {
+public class AnalysisEngineDescription_implTest {
+
+  public @Rule TestRule exceptingHandlingRule = new PrintExceptionsWhenRunFromCommandLineRule();
 
   // Text encoding to use for the various byte/character conversions happening in this test case.
   // Public because also used by other test cases.
   public static final String encoding = "utf-8";
-  
+
   private static final File TEST_DATA_FILE = JUnitExtension
       .getFile("ResourceTest/ResourceManager_implTest_tempDataFile.dat");
-  
-  private AnalysisEngineDescription primitiveDesc;
 
+  private XMLParser xmlParser;
+  private AnalysisEngineDescription primitiveDesc;
   private AnalysisEngineDescription aggregateDesc;
-  
-  /**
-   * Constructor for AnalysisEngineDescription_implTest.
-   * 
-   * @param arg0
-   */
-  public AnalysisEngineDescription_implTest(String arg0) {
-    super(arg0);
-  }
 
-  /**
-   * @see TestCase#setUp()
-   */
-  @Override
-  protected void setUp() throws Exception {
-    try {
-      super.setUp();
-      UIMAFramework.getXMLParser().enableSchemaValidation(true);
-      
-      TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
-      TypeDescription type1 = typeSystem.addType("Fake", "<b>Fake</b> Type", "Annotation");
-      type1.addFeature("TestFeature", "For Testing Only",
-              CAS.TYPE_NAME_STRING);
-      TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type",
-              "uima.cas.String");
-      enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"),
-          new AllowedValue_impl("Two", "Second Value") });
-
-      TypePriorities typePriorities = new TypePriorities_impl();
-      TypePriorityList priorityList = typePriorities.addPriorityList();
-      priorityList.addType("Fake");
-      priorityList.addType("EnumType");
-
-      FsIndexDescription index = new FsIndexDescription_impl();
-      index.setLabel("testIndex");
-      index.setTypeName("Fake");
-      FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl();
-      key1.setFeatureName("TestFeature");
-      key1.setComparator(1);
-      FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl();
-      key2.setFeatureName("Start");
-      key2.setComparator(0);
-      FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl();
-      key3.setTypePriority(true);
-      index.setKeys(new FsIndexKeyDescription[] { key1, key2, key3 });
-
-      FsIndexDescription index2 = new FsIndexDescription_impl();
-      index2.setLabel("testIndex2");
-      index2.setTypeName("Fake");
-      index2.setKind(FsIndexDescription.KIND_SET);
-      FsIndexKeyDescription key1a = new FsIndexKeyDescription_impl();
-      key1a.setFeatureName("TestFeature");
-      key1a.setComparator(1);
-      index2.setKeys(new FsIndexKeyDescription[] { key1a });
-
-      // create primitive AE description
-      primitiveDesc = new AnalysisEngineDescription_impl();
-      primitiveDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
-      primitiveDesc.setPrimitive(true);
-      primitiveDesc.setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator");
-      AnalysisEngineMetaData md = primitiveDesc.getAnalysisEngineMetaData();
-      md.setName("Test TAE");
-      md.setDescription("Does not do anything useful.");
-      md.setVersion("1.0");
-      md.setTypeSystem(typeSystem);
-      md.setTypePriorities(typePriorities);
-      md.setFsIndexes(new FsIndexDescription[] { index, index2 });
-      Capability cap1 = new Capability_impl();
-      cap1.setDescription("First fake capability");
-      cap1.addOutputType("Fake", false);
-      cap1.addOutputFeature("Fake:TestFeature");
-      Capability cap2 = new Capability_impl();
-      cap2.setDescription("Second fake capability");
-      cap2.addInputType("Fake", true);
-      cap2.addOutputType("Fake", true);
-      // SimplePrecondition precond1 = new SimplePrecondition_impl();
-      // precond1.setFeatureDescription(feature1);
-      // precond1.setComparisonValue(new String[]{"en,de"});
-      // precond1.setPredicate(SimplePrecondition.LANGUAGE_SUBSUMED);
-      // cap1.setPreconditions(new Precondition[]{precond1});
-      cap1.setLanguagesSupported(new String[] { "en", "de" });
-      cap1.setMimeTypesSupported(new String[] { "text/plain" });
-      md.setCapabilities(new Capability[] { cap1, cap2 });
-      ConfigurationParameter cfgParam1 = new ConfigurationParameter_impl();
-      cfgParam1.setName("param1");
-      cfgParam1.setDescription("Test Parameter 1");
-      cfgParam1.setType("String");
-      ConfigurationParameter cfgParam2 = new ConfigurationParameter_impl();
-      cfgParam2.setName("param2");
-      cfgParam2.setDescription("Test Parameter 2");
-      cfgParam2.setType("Integer");
-      ConfigurationGroup cfgGrp1 = new ConfigurationGroup_impl();
-      cfgGrp1.setNames(new String[] { "cfgGrp1" });
-      cfgGrp1.setConfigurationParameters(new ConfigurationParameter[] { cfgParam1, cfgParam2 });
-      ConfigurationParameter cfgParam3 = new ConfigurationParameter_impl();
-      cfgParam3.setName("param3");
-      cfgParam3.setDescription("Test Parameter 3");
-      cfgParam3.setType("Float");
-      ConfigurationGroup cfgGrp2 = new ConfigurationGroup_impl();
-      cfgGrp2.setNames(new String[] { "cfgGrp2a", "cfgGrp2b" });
-      cfgGrp2.setConfigurationParameters(new ConfigurationParameter[] { cfgParam3 });
-      md.getConfigurationParameterDeclarations().setConfigurationGroups(
-              new ConfigurationGroup[] { cfgGrp1, cfgGrp2 });
-
-      NameValuePair nvp1 = new NameValuePair_impl("param1", "test");
-      NameValuePair nvp2 = new NameValuePair_impl("param2", Integer.valueOf("42"));
-      NameValuePair nvp3a = new NameValuePair_impl("param3", Float.valueOf("2.718281828459045"));
-      NameValuePair nvp3b = new NameValuePair_impl("param3", Float.valueOf("3.1415927"));
-      ConfigurationParameterSettings settings = md.getConfigurationParameterSettings();
-      settings.getSettingsForGroups().put("cfgGrp1", new NameValuePair[] { nvp1, nvp2 });
-      settings.getSettingsForGroups().put("cfgGrp2a", new NameValuePair[] { nvp3a });
-      settings.getSettingsForGroups().put("cfgGrp2b", new NameValuePair[] { nvp3b });
-
-      // create aggregate AE description
-      aggregateDesc = new AnalysisEngineDescription_impl();
-      aggregateDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
-      aggregateDesc.setPrimitive(false);
-      Map<String, MetaDataObject> delegateTaeMap = aggregateDesc.getDelegateAnalysisEngineSpecifiersWithImports();
-      delegateTaeMap.put("Test", primitiveDesc);
-      AnalysisEngineDescription_impl primDesc2 = new AnalysisEngineDescription_impl();
-      primDesc2.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
-      primDesc2.setPrimitive(true);
-      primDesc2.setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator");
-      primDesc2.getAnalysisEngineMetaData().setName("fakeAnnotator");
-      primDesc2.getAnalysisEngineMetaData().setCapabilities(
-              new Capability[] { new Capability_impl() });
-      delegateTaeMap.put("Empty", primDesc2);
-      // Can't use URI specifier if we try to produce resource, because it maps to either a SOAP or VINCI adapter,
-      //   and that adapter is not on the class path for this causes a failure in loading
-//      URISpecifier uriSpec = new URISpecifier_impl();
-//      uriSpec.setUri("http://incubator.apache.org/uima");
-//      uriSpec.setProtocol(Constants.PROTOCOL_SOAP);
-      FileResourceSpecifier fileResSpec = new FileResourceSpecifier_impl();
-      fileResSpec.setFileUrl(TEST_DATA_FILE.toURL().toString());
-      FlowControllerDeclaration fcDecl = new FlowControllerDeclaration_impl();
-      fcDecl.setKey("TestFlowController");
-      FlowControllerDescription fcDesc = new FlowControllerDescription_impl();
-      fcDesc.getMetaData().setName("MyTestFlowController");
-      fcDesc.setImplementationName("org.apache.uima.analysis_engine.impl.FlowControllerForErrorTest");
-      fcDecl.setSpecifier(fcDesc);
-      aggregateDesc.setFlowControllerDeclaration(fcDecl);
-
-      ExternalResourceDependency dep = UIMAFramework.getResourceSpecifierFactory()
-              .createExternalResourceDependency();
-      dep.setKey("ResourceKey");
-      dep.setDescription("Test");
-      aggregateDesc.setExternalResourceDependencies(new ExternalResourceDependency[] { dep });
-      ResourceManagerConfiguration resMgrCfg = UIMAFramework.getResourceSpecifierFactory()
-              .createResourceManagerConfiguration();
-      ExternalResourceDescription extRes = UIMAFramework.getResourceSpecifierFactory()
-              .createExternalResourceDescription();
-      extRes.setResourceSpecifier(fileResSpec);
-      extRes.setName("Resource1");
-      extRes.setDescription("Test");
-      resMgrCfg.setExternalResources(new ExternalResourceDescription[] { extRes });
-
-      ExternalResourceBinding binding = UIMAFramework.getResourceSpecifierFactory()
-              .createExternalResourceBinding();
-      binding.setKey("ResourceKey");
-      binding.setResourceName("Resource1");
-      resMgrCfg.setExternalResourceBindings(new ExternalResourceBinding[] {binding});
-      aggregateDesc.setResourceManagerConfiguration(resMgrCfg);
-
-      // AsbCreationSpecifier asbSpec = new AsbCreationSpecifier_impl();
-      // asbSpec.getAsbMetaData().setAsynchronousModeSupported(true);
-      // asbSpec.getAsbMetaData().setSupportedProtocols(new String[]{Constants.PROTOCOL_SOAP});
-      // aggregateDesc.setAsbSpecifier(asbSpec);
-      // AnalysisSequencerCrea1tionSpecifier seqSpec = new
-      // AnalysisSequencerCreationSpecifier_impl();
-      // seqSpec.getAnalysisSequencerMetaData().setSupportedPreconditionTypes(
-      // new String[]{SimplePrecondition.PRECONDITION_TYPE});
-      // aggregateDesc.setSequencerSpecifier(seqSpec);
-      md = aggregateDesc.getAnalysisEngineMetaData();
-      md.setName("Test Aggregate TAE");
-      md.setDescription("Does not do anything useful.");
-      md.setVersion("1.0");
-      // md.setTypeSystem(typeSystem);
-      // md.setFsIndexes(new FsIndexDescription[]{index});
-      md.setCapabilities(primitiveDesc.getAnalysisEngineMetaData().getCapabilities());
-      FixedFlow fixedFlow = new FixedFlow_impl();
-      fixedFlow.setFixedFlow(new String[] { "Test", "Empty" });
-      md.setFlowConstraints(fixedFlow);
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
-    }
+  @Before
+  public void setUp() throws Exception {
+    xmlParser = UIMAFramework.getXMLParser();
+    xmlParser.enableSchemaValidation(true);
+
+    TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
+    TypeDescription type1 = typeSystem.addType("Fake", "<b>Fake</b> Type", "Annotation");
+    type1.addFeature("TestFeature", "For Testing Only", CAS.TYPE_NAME_STRING);
+    TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type",
+        "uima.cas.String");
+    enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"),
+        new AllowedValue_impl("Two", "Second Value") });
+
+    TypePriorities typePriorities = new TypePriorities_impl();
+    TypePriorityList priorityList = typePriorities.addPriorityList();
+    priorityList.addType("Fake");
+    priorityList.addType("EnumType");
+
+    FsIndexDescription index = new FsIndexDescription_impl();
+    index.setLabel("testIndex");
+    index.setTypeName("Fake");
+    FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl();
+    key1.setFeatureName("TestFeature");
+    key1.setComparator(1);
+    FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl();
+    key2.setFeatureName("Start");
+    key2.setComparator(0);
+    FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl();
+    key3.setTypePriority(true);
+    index.setKeys(new FsIndexKeyDescription[] { key1, key2, key3 });
+
+    FsIndexDescription index2 = new FsIndexDescription_impl();
+    index2.setLabel("testIndex2");
+    index2.setTypeName("Fake");
+    index2.setKind(FsIndexDescription.KIND_SET);
+    FsIndexKeyDescription key1a = new FsIndexKeyDescription_impl();
+    key1a.setFeatureName("TestFeature");
+    key1a.setComparator(1);
+    index2.setKeys(new FsIndexKeyDescription[] { key1a });
+
+    // create primitive AE description
+    primitiveDesc = new AnalysisEngineDescription_impl();
+    primitiveDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
+    primitiveDesc.setPrimitive(true);
+    primitiveDesc
+        .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator");
+    AnalysisEngineMetaData md = primitiveDesc.getAnalysisEngineMetaData();
+    md.setName("Test TAE");
+    md.setDescription("Does not do anything useful.");
+    md.setVersion("1.0");
+    md.setTypeSystem(typeSystem);
+    md.setTypePriorities(typePriorities);
+    md.setFsIndexes(new FsIndexDescription[] { index, index2 });
+    Capability cap1 = new Capability_impl();
+    cap1.setDescription("First fake capability");
+    cap1.addOutputType("Fake", false);
+    cap1.addOutputFeature("Fake:TestFeature");
+    Capability cap2 = new Capability_impl();
+    cap2.setDescription("Second fake capability");
+    cap2.addInputType("Fake", true);
+    cap2.addOutputType("Fake", true);
+    // SimplePrecondition precond1 = new SimplePrecondition_impl();
+    // precond1.setFeatureDescription(feature1);
+    // precond1.setComparisonValue(new String[]{"en,de"});
+    // precond1.setPredicate(SimplePrecondition.LANGUAGE_SUBSUMED);
+    // cap1.setPreconditions(new Precondition[]{precond1});
+    cap1.setLanguagesSupported(new String[] { "en", "de" });
+    cap1.setMimeTypesSupported(new String[] { "text/plain" });
+    md.setCapabilities(new Capability[] { cap1, cap2 });
+    ConfigurationParameter cfgParam1 = new ConfigurationParameter_impl();
+    cfgParam1.setName("param1");
+    cfgParam1.setDescription("Test Parameter 1");
+    cfgParam1.setType("String");
+    ConfigurationParameter cfgParam2 = new ConfigurationParameter_impl();
+    cfgParam2.setName("param2");
+    cfgParam2.setDescription("Test Parameter 2");
+    cfgParam2.setType("Integer");
+    ConfigurationGroup cfgGrp1 = new ConfigurationGroup_impl();
+    cfgGrp1.setNames(new String[] { "cfgGrp1" });
+    cfgGrp1.setConfigurationParameters(new ConfigurationParameter[] { cfgParam1, cfgParam2 });
+    ConfigurationParameter cfgParam3 = new ConfigurationParameter_impl();
+    cfgParam3.setName("param3");
+    cfgParam3.setDescription("Test Parameter 3");
+    cfgParam3.setType("Float");
+    ConfigurationGroup cfgGrp2 = new ConfigurationGroup_impl();
+    cfgGrp2.setNames(new String[] { "cfgGrp2a", "cfgGrp2b" });
+    cfgGrp2.setConfigurationParameters(new ConfigurationParameter[] { cfgParam3 });
+    md.getConfigurationParameterDeclarations()
+        .setConfigurationGroups(new ConfigurationGroup[] { cfgGrp1, cfgGrp2 });
+
+    NameValuePair nvp1 = new NameValuePair_impl("param1", "test");
+    NameValuePair nvp2 = new NameValuePair_impl("param2", Integer.valueOf("42"));
+    NameValuePair nvp3a = new NameValuePair_impl("param3", Float.valueOf("2.718281828459045"));
+    NameValuePair nvp3b = new NameValuePair_impl("param3", Float.valueOf("3.1415927"));
+    ConfigurationParameterSettings settings = md.getConfigurationParameterSettings();
+    settings.getSettingsForGroups().put("cfgGrp1", new NameValuePair[] { nvp1, nvp2 });
+    settings.getSettingsForGroups().put("cfgGrp2a", new NameValuePair[] { nvp3a });
+    settings.getSettingsForGroups().put("cfgGrp2b", new NameValuePair[] { nvp3b });
+
+    // create aggregate AE description
+    aggregateDesc = new AnalysisEngineDescription_impl();
+    aggregateDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
+    aggregateDesc.setPrimitive(false);
+    Map<String, MetaDataObject> delegateTaeMap = aggregateDesc
+        .getDelegateAnalysisEngineSpecifiersWithImports();
+    delegateTaeMap.put("Test", primitiveDesc);
+    AnalysisEngineDescription_impl primDesc2 = new AnalysisEngineDescription_impl();
+    primDesc2.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
+    primDesc2.setPrimitive(true);
+    primDesc2.setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator");
+    primDesc2.getAnalysisEngineMetaData().setName("fakeAnnotator");
+    primDesc2.getAnalysisEngineMetaData()
+        .setCapabilities(new Capability[] { new Capability_impl() });
+    delegateTaeMap.put("Empty", primDesc2);
+    // Can't use URI specifier if we try to produce resource, because it maps to either a SOAP or
+    // VINCI adapter,
+    // and that adapter is not on the class path for this causes a failure in loading
+    // URISpecifier uriSpec = new URISpecifier_impl();
+    // uriSpec.setUri("http://incubator.apache.org/uima");
+    // uriSpec.setProtocol(Constants.PROTOCOL_SOAP);
+    FileResourceSpecifier fileResSpec = new FileResourceSpecifier_impl();
+    fileResSpec.setFileUrl(TEST_DATA_FILE.toURL().toString());
+    FlowControllerDeclaration fcDecl = new FlowControllerDeclaration_impl();
+    fcDecl.setKey("TestFlowController");
+    FlowControllerDescription fcDesc = new FlowControllerDescription_impl();
+    fcDesc.getMetaData().setName("MyTestFlowController");
+    fcDesc.setImplementationName("org.apache.uima.analysis_engine.impl.FlowControllerForErrorTest");
+    fcDecl.setSpecifier(fcDesc);
+    aggregateDesc.setFlowControllerDeclaration(fcDecl);
+
+    ExternalResourceDependency dep = UIMAFramework.getResourceSpecifierFactory()
+        .createExternalResourceDependency();
+    dep.setKey("ResourceKey");
+    dep.setDescription("Test");
+    aggregateDesc.setExternalResourceDependencies(new ExternalResourceDependency[] { dep });
+    ResourceManagerConfiguration resMgrCfg = UIMAFramework.getResourceSpecifierFactory()
+        .createResourceManagerConfiguration();
+    ExternalResourceDescription extRes = UIMAFramework.getResourceSpecifierFactory()
+        .createExternalResourceDescription();
+    extRes.setResourceSpecifier(fileResSpec);
+    extRes.setName("Resource1");
+    extRes.setDescription("Test");
+    resMgrCfg.setExternalResources(new ExternalResourceDescription[] { extRes });
+
+    ExternalResourceBinding binding = UIMAFramework.getResourceSpecifierFactory()
+        .createExternalResourceBinding();
+    binding.setKey("ResourceKey");
+    binding.setResourceName("Resource1");
+    resMgrCfg.setExternalResourceBindings(new ExternalResourceBinding[] { binding });
+    aggregateDesc.setResourceManagerConfiguration(resMgrCfg);
+
+    // AsbCreationSpecifier asbSpec = new AsbCreationSpecifier_impl();
+    // asbSpec.getAsbMetaData().setAsynchronousModeSupported(true);
+    // asbSpec.getAsbMetaData().setSupportedProtocols(new String[]{Constants.PROTOCOL_SOAP});
+    // aggregateDesc.setAsbSpecifier(asbSpec);
+    // AnalysisSequencerCrea1tionSpecifier seqSpec = new
+    // AnalysisSequencerCreationSpecifier_impl();
+    // seqSpec.getAnalysisSequencerMetaData().setSupportedPreconditionTypes(
+    // new String[]{SimplePrecondition.PRECONDITION_TYPE});
+    // aggregateDesc.setSequencerSpecifier(seqSpec);
+    md = aggregateDesc.getAnalysisEngineMetaData();
+    md.setName("Test Aggregate TAE");
+    md.setDescription("Does not do anything useful.");
+    md.setVersion("1.0");
+    // md.setTypeSystem(typeSystem);
+    // md.setFsIndexes(new FsIndexDescription[]{index});
+    md.setCapabilities(primitiveDesc.getAnalysisEngineMetaData().getCapabilities());
+    FixedFlow fixedFlow = new FixedFlow_impl();
+    fixedFlow.setFixedFlow(new String[] { "Test", "Empty" });
+    md.setFlowConstraints(fixedFlow);
   }
 
-  @Override
-  public void tearDown() {
+  @After
+  public void tearDown() throws Exception {
+    // Note that the XML parser is a singleton in the framework, so we have to set this back to the
+    // default.
+    xmlParser.enableSchemaValidation(false);
     primitiveDesc = null;
     aggregateDesc = null;
   }
-  
+
+  @Test
   public void testMulticoreInitialize() throws Exception {
     ResourceManager resourceManager = UIMAFramework.newDefaultResourceManager();
     ConfigurationManager configManager = UIMAFramework.newConfigurationManager();
     Logger logger = UIMAFramework.getLogger(this.getClass());
     logger.setResourceManager(resourceManager);
- 
+
     UimaContext uimaContext = UIMAFramework.newUimaContext(logger, resourceManager, configManager);
-    
+
     final Map<String, Object> p = new HashMap<String, Object>();
-    p.put(UIMAFramework.CAS_INITIAL_HEAP_SIZE,  200);
+    p.put(UIMAFramework.CAS_INITIAL_HEAP_SIZE, 200);
     p.put(Resource.PARAM_CONFIG_MANAGER, configManager);
-    p.put(Resource.PARAM_RESOURCE_MANAGER,  UIMAFramework.newDefaultResourceManager());
+    p.put(Resource.PARAM_RESOURCE_MANAGER, UIMAFramework.newDefaultResourceManager());
     p.put(Resource.PARAM_UIMA_CONTEXT, uimaContext);
-    int numberOfThreads = Math.min(50, Utilities.numberOfCores * 5); 
+    int numberOfThreads = Math.min(50, Utilities.numberOfCores * 5);
     final AnalysisEngine[] aes = new AnalysisEngine[numberOfThreads];
-    System.out.format("test multicore initialize with %d threads%n",
-        numberOfThreads);
-    
-    
+    System.out.format("test multicore initialize with %d threads%n", numberOfThreads);
+
     MultiThreadUtils.Run2isb run2isb = new MultiThreadUtils.Run2isb() {
-      
       public void call(int i, int r, StringBuilder sb) throws Exception {
         Random random = new Random();
         for (int j = 0; j < 2; j++) {
-          aes[i] = UIMAFramework.produceAnalysisEngine(primitiveDesc, p);     
-  //        System.out.println(sb.toString());
-  //        System.out.print('.');
+          aes[i] = UIMAFramework.produceAnalysisEngine(primitiveDesc, p);
+          // System.out.println(sb.toString());
+          // System.out.print('.');
           if ((i % 2) == 0) {
             Thread.sleep(0, random.nextInt(2000));
           }
         }
       }
-    };  
-    MultiThreadUtils.tstMultiThread("MultiCoreInitialize",  numberOfThreads,  100, run2isb, MultiThreadUtils.emptyReset);
-    assertTrue(!aes[0].equals(aes[1]));
-    
+    };
+    MultiThreadUtils.tstMultiThread("MultiCoreInitialize", numberOfThreads, 100, run2isb,
+        MultiThreadUtils.emptyReset);
+    assertThat(aes[0]).isNotEqualTo(aes[1]);
+
     run2isb = new MultiThreadUtils.Run2isb() {
-      
       public void call(int i, int r, StringBuilder sb) throws Exception {
         Random random = new Random();
         for (int j = 0; j < 2; j++) {
-          aes[i] = UIMAFramework.produceAnalysisEngine(aggregateDesc, p);     
-  //        System.out.println(sb.toString());
-  //        System.out.print('.');
+          aes[i] = UIMAFramework.produceAnalysisEngine(aggregateDesc, p);
+          // System.out.println(sb.toString());
+          // System.out.print('.');
           if ((i % 2) == 0) {
             Thread.sleep(0, random.nextInt(5000));
           }
         }
       }
     };
-    MultiThreadUtils.tstMultiThread("MultiCoreInitialize",  numberOfThreads,  100, run2isb, MultiThreadUtils.emptyReset);
-    assertTrue(!aes[0].equals(aes[1]));
 
-    
-//    System.out.println("");
+    MultiThreadUtils.tstMultiThread("MultiCoreInitialize", numberOfThreads, 100, run2isb,
+        MultiThreadUtils.emptyReset);
+
+    assertThat(aes[0]).isNotEqualTo(aes[1]);
   }
-  
-  
-  
-  public void testXMLization() throws Exception {
-    try {
-      // write objects to XML
-
-      StringWriter writer = new StringWriter();
-      primitiveDesc.toXML(writer);
-      String primitiveDescXml = writer.getBuffer().toString();
-      // System.out.println(primitiveDescXml);
-      writer = new StringWriter();
-      aggregateDesc.toXML(writer);
-      String aggregateDescXml = writer.getBuffer().toString();
-      // System.out.println(aggregateDescXml);
-
-      // parse objects from XML
-      InputStream is = new ByteArrayInputStream(primitiveDescXml.getBytes(encoding));
-      AnalysisEngineDescription newPrimitiveDesc = (AnalysisEngineDescription) UIMAFramework
-              .getXMLParser().parse(new XMLInputSource(is, null));
-      is = new ByteArrayInputStream(aggregateDescXml.getBytes(encoding));
-      AnalysisEngineDescription newAggregateDesc = (AnalysisEngineDescription) UIMAFramework
-              .getXMLParser().parse(new XMLInputSource(is, null));
-
-      Assert.assertEquals(primitiveDesc, newPrimitiveDesc);
-      Assert.assertEquals(aggregateDesc, newAggregateDesc);
-
-      // test a complex descriptor
-      XMLInputSource in = new XMLInputSource(JUnitExtension
-              .getFile("AnnotatorContextTest/AnnotatorWithGroupsAndNonGroupParams.xml"));
-      AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-      OperationalProperties opProps = desc.getAnalysisEngineMetaData().getOperationalProperties();
-      assertNotNull(opProps);
-      assertEquals(true, opProps.getModifiesCas());
-      assertEquals(true, opProps.isMultipleDeploymentAllowed());
-      writer = new StringWriter();
-      desc.toXML(writer);
-      String descXml = writer.getBuffer().toString();
-      is = new ByteArrayInputStream(descXml.getBytes(encoding));
-      AnalysisEngineDescription newDesc = (AnalysisEngineDescription) UIMAFramework.getXMLParser()
-              .parse(new XMLInputSource(is, null));
-      Assert.assertEquals(desc, newDesc);
-
-      // test a descriptor that includes a CasConsumer
-      in = new XMLInputSource(JUnitExtension
-              .getFile("TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml"));
-      desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-      writer = new StringWriter();
-      desc.toXML(writer);
-      descXml = writer.getBuffer().toString();
-      is = new ByteArrayInputStream(descXml.getBytes(encoding));
-      newDesc = (AnalysisEngineDescription) UIMAFramework.getXMLParser().parse(
-              new XMLInputSource(is, null));
-      Assert.assertEquals(desc, newDesc);
-
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
+
+  @Test
+  public void thatComplexDescriptorCanBeXMLized() throws Exception {
+    // test a complex descriptor
+    AnalysisEngineDescription desc = xmlParser.parseAnalysisEngineDescription(new XMLInputSource(
+        getFile("AnnotatorContextTest/AnnotatorWithGroupsAndNonGroupParams.xml")));
+    OperationalProperties opProps = desc.getAnalysisEngineMetaData().getOperationalProperties();
+
+    assertThat(opProps).isNotNull();
+    assertThat(opProps.getModifiesCas()).isTrue();
+    assertThat(opProps.isMultipleDeploymentAllowed()).isTrue();
+
+    try (InputStream is = new ByteArrayInputStream(toXmlString(desc).getBytes(encoding))) {
+      AnalysisEngineDescription newDesc = xmlParser
+          .parseAnalysisEngineDescription(new XMLInputSource(is, null));
+      assertThat(newDesc).isEqualTo(desc);
+    }
+  }
+
+  @Test
+  public void thatDescriptorWithCasConsumerCanBeXMLized() throws Exception {
+    // test a descriptor that includes a CasConsumer
+    AnalysisEngineDescription desc = xmlParser.parseAnalysisEngineDescription(
+        new XMLInputSource(getFile("TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml")));
+    try (InputStream is = new ByteArrayInputStream(toXmlString(desc).getBytes(encoding))) {
+      AnalysisEngineDescription newDesc = xmlParser
+          .parseAnalysisEngineDescription(new XMLInputSource(is, null));
+      assertThat(newDesc).isEqualTo(desc);
+    }
+  }
+
+  @Test
+  public void thatPrimitiveDescriptorCanBeXMLized() throws Exception {
+    // write objects to XML
+    String primitiveDescXml = toXmlString(primitiveDesc);
+
+    // parse objects from XML
+    try (InputStream is = new ByteArrayInputStream(primitiveDescXml.getBytes(encoding))) {
+      AnalysisEngineDescription newPrimitiveDesc = xmlParser
+          .parseAnalysisEngineDescription(new XMLInputSource(is, null));
+      assertThat(newPrimitiveDesc).isEqualTo(primitiveDesc);
+    }
+  }
+
+  @Test
+  public void thatAggregateDescriptorCanBeXMLized() throws Exception {
+    String aggregateDescXml = toXmlString(aggregateDesc);
+    try (InputStream is = new ByteArrayInputStream(aggregateDescXml.getBytes(encoding))) {
+      AnalysisEngineDescription newAggregateDesc = xmlParser
+          .parseAnalysisEngineDescription(new XMLInputSource(is, null));
+      assertThat(newAggregateDesc).isEqualTo(aggregateDesc);
     }
   }
- 
+
+  @Test
   public void testDefaultingOperationalParameters() throws Exception {
     XMLInputSource in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/TestPrimitiveOperationalParmsDefaults.xml"));
-    AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
+        .getFile("TextAnalysisEngineImplTest/TestPrimitiveOperationalParmsDefaults.xml"));
+    AnalysisEngineDescription desc = xmlParser.parseAnalysisEngineDescription(in);
     OperationalProperties opProps = desc.getAnalysisEngineMetaData().getOperationalProperties();
-    assertNotNull(opProps);
-    assertEquals(true, opProps.getModifiesCas());
-    assertEquals(false, opProps.isMultipleDeploymentAllowed());
-  }
-
-  public void testSerialization() throws Exception {
-    try {
-      // serialize objects to byte array
 
-      byte[] primitiveDescBytes = SerializationUtils.serialize(primitiveDesc);
-      byte[] aggregateDescBytes = SerializationUtils.serialize(aggregateDesc);
+    assertThat(opProps).isNotNull();
+    assertThat(opProps.getModifiesCas()).isTrue();
+    assertThat(opProps.isMultipleDeploymentAllowed()).isFalse();
+  }
 
-      // deserialize
-      AnalysisEngineDescription newPrimitiveDesc = (AnalysisEngineDescription) SerializationUtils
-              .deserialize(primitiveDescBytes);
-      AnalysisEngineDescription newAggregateDesc = (AnalysisEngineDescription) SerializationUtils
-              .deserialize(aggregateDescBytes);
+  @Test
+  public void thatPrimitiveDescriptionCanBeSerialized() throws Exception {
+    byte[] primitiveDescBytes = SerializationUtils.serialize(primitiveDesc);
+    AnalysisEngineDescription newPrimitiveDesc = (AnalysisEngineDescription) SerializationUtils
+        .deserialize(primitiveDescBytes);
+    assertThat(newPrimitiveDesc).isEqualTo(primitiveDesc);
+  }
 
-      Assert.assertEquals(primitiveDesc, newPrimitiveDesc);
-      Assert.assertEquals(aggregateDesc, newAggregateDesc);
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
-    }
+  @Test
+  public void thatAggregateDescriptionCanBeSerialized() throws Exception {
+    byte[] aggregateDescBytes = SerializationUtils.serialize(aggregateDesc);
+    AnalysisEngineDescription newAggregateDesc = (AnalysisEngineDescription) SerializationUtils
+        .deserialize(aggregateDescBytes);
+    assertThat(newAggregateDesc).isEqualTo(aggregateDesc);
   }
 
+  @Test
   public void testDelegateImports() throws Exception {
     // create aggregate TAE description and add delegate AE import
     AnalysisEngineDescription testAgg = new AnalysisEngineDescription_impl();
-    Map<String, MetaDataObject> delegateMap = testAgg.getDelegateAnalysisEngineSpecifiersWithImports();
+    Map<String, MetaDataObject> delegateMap = testAgg
+        .getDelegateAnalysisEngineSpecifiersWithImports();
     Import_impl delegateImport = new Import_impl();
-    delegateImport.setLocation(JUnitExtension.getFile(
-            "TextAnalysisEngineImplTest/TestPrimitiveTae1.xml").toURI().toURL().toString());
+    delegateImport.setLocation(
+        getFile("TextAnalysisEngineImplTest/TestPrimitiveTae1.xml").toURI().toURL().toString());
     delegateMap.put("key", delegateImport);
 
-    // test that import is resolved
-    Map<String, ResourceSpecifier> mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers();
-    assertEquals(1, mapWithImportsResolved.size());
-    ResourceSpecifier obj = mapWithImportsResolved.values().iterator().next();
-    assertTrue(obj instanceof AnalysisEngineDescription);
+    assertThat(testAgg.getDelegateAnalysisEngineSpecifiers().values()) //
+        .as("test that import is resolved") //
+        .hasSize(1) //
+        .allMatch(d -> d instanceof AnalysisEngineDescription);
 
-    // test that remove works
     delegateMap.remove("key");
-    mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers();
-    assertEquals(0, mapWithImportsResolved.size());
+    assertThat(testAgg.getDelegateAnalysisEngineSpecifiers()) //
+        .as("test that remove works") //
+        .isEmpty();
 
-    // test the re-add works
     delegateMap.put("key", delegateImport);
-    mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers();
-    assertEquals(1, mapWithImportsResolved.size());
-    obj = mapWithImportsResolved.values().iterator().next();
-    assertTrue(obj instanceof AnalysisEngineDescription);
+    assertThat(testAgg.getDelegateAnalysisEngineSpecifiers().values()) //
+        .as("test the re-add works") //
+        .hasSize(1) //
+        .allMatch(d -> d instanceof AnalysisEngineDescription);
 
     // serialize to XML, preserving imports
     testAgg.toXML(new StringWriter(), true);
-
-    // verify that imports are still resolved
-    mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers();
-    assertEquals(1, mapWithImportsResolved.size());
-    obj = mapWithImportsResolved.values().iterator().next();
-    assertTrue(obj instanceof AnalysisEngineDescription);
+    assertThat(testAgg.getDelegateAnalysisEngineSpecifiers().values()) //
+        .as("verify that imports are still resolved") //
+        .hasSize(1) //
+        .allMatch(d -> d instanceof AnalysisEngineDescription);
   }
 
+  @Test
   public void testDoFullValidation() throws Exception {
     // try some descriptors that are invalid due to config. param problems
     for (int i = 1; i <= 13; i++) {
-      _testInvalidDescriptor(JUnitExtension
-              .getFile("TextAnalysisEngineImplTest/InvalidConfigParams" + i + ".xml"));
+      assertDescriptorIsNotValid("TextAnalysisEngineImplTest/InvalidConfigParams" + i + ".xml");
     }
+
     // try a descriptor that's invalid due to an unsatisfied resource dependency
-    _testInvalidDescriptor(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/UnsatisfiedResourceDependency.xml"));
+    assertDescriptorIsNotValid("TextAnalysisEngineImplTest/UnsatisfiedResourceDependency.xml");
+
     // try some invalid operational properties
-    _testInvalidDescriptor(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/InvalidAggregateSegmenter.xml"));
+    assertDescriptorIsNotValid("TextAnalysisEngineImplTest/InvalidAggregateSegmenter.xml");
+
     // invalid fs indexes
-    _testInvalidDescriptor(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/InvalidFsIndexes.xml"));
+    assertDescriptorIsNotValid("TextAnalysisEngineImplTest/InvalidFsIndexes.xml");
+
     // circular import
-    _testInvalidDescriptor(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/AggregateThatImportsItself.xml"));
+    assertDescriptorIsNotValid("TextAnalysisEngineImplTest/AggregateThatImportsItself.xml");
 
     // try some that should work
-    XMLInputSource in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOverrides.xml"));
-    AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
-    in = new XMLInputSource(JUnitExtension
-            .getFile("AnnotatorContextTest/AnnotatorWithGroupsAndNonGroupParams.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
+    assertDescriptorIsValid("TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOverrides.xml");
+
+    assertDescriptorIsValid("AnnotatorContextTest/AnnotatorWithGroupsAndNonGroupParams.xml");
 
     // try aggregate containing remote service - should work even if can't connect
-    in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/AggregateWithUnknownRemoteComponent.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
+    assertDescriptorIsValid("TextAnalysisEngineImplTest/AggregateWithUnknownRemoteComponent.xml");
 
     // try aggregate with sofas
-    in = new XMLInputSource(JUnitExtension.getFile("CpeSofaTest/TransAnnotatorAggregate.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
+    assertDescriptorIsValid("CpeSofaTest/TransAnnotatorAggregate.xml");
 
     // try another aggregate with sofas
-    in = new XMLInputSource(JUnitExtension
-            .getFile("CpeSofaTest/TransAnnotatorAndTestAnnotatorAggregate.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
+    assertDescriptorIsValid("CpeSofaTest/TransAnnotatorAndTestAnnotatorAggregate.xml");
 
     // try primitive with duplicate configuration group definitions
-    in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/AnnotatorWithDuplicateConfigurationGroups.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
+    assertDescriptorIsValid(
+        "TextAnalysisEngineImplTest/AnnotatorWithDuplicateConfigurationGroups.xml");
 
     // try aggregate with duplicate configuration group definitions
-    in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/AggregateWithDuplicateGroupOverrides.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
-    
-    //test aggregate with import by name and configuration parameter overrides
-    in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndImportByName.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    ResourceManager resMgr = UIMAFramework.newDefaultResourceManager();
-    File dataPathDir = JUnitExtension.getFile("TextAnalysisEngineImplTest/dataPathDir");
+    assertDescriptorIsValid("TextAnalysisEngineImplTest/AggregateWithDuplicateGroupOverrides.xml");
+
+    // test UIMA C++ descriptor (should succeed even though annotator library doesn't exist)
+    assertDescriptorIsValid("TextAnalysisEngineImplTest/TestUimaCppAe.xml");
+
+    assertDescriptorIsValid("TextAnalysisEngineImplTest/TestAggregateContainingCppAnnotator.xml");
+  }
+
+  @Test
+  public void thatAggregateWithImportByNameAndConfigParameterOverridesValidates() throws Exception {
+    // test aggregate with import by name and configuration parameter overrides
+    XMLInputSource in = new XMLInputSource(
+        getFile("TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndImportByName.xml"));
+    AnalysisEngineDescription desc = xmlParser.parseAnalysisEngineDescription(in);
+    ResourceManager resMgr = newDefaultResourceManager();
+    File dataPathDir = getFile("TextAnalysisEngineImplTest/dataPathDir");
     resMgr.setDataPath(dataPathDir.getCanonicalPath());
     desc.doFullValidation(resMgr);
-    
-    //test UIMA C++ descriptor (should succeed even though annotator library doesn't exist)
-    in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/TestUimaCppAe.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();
-    
-    in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/TestAggregateContainingCppAnnotator.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    desc.doFullValidation();    
   }
-  
+
+  @Test
   public void testValidate() throws Exception {
-    //test aggregate with import by name and configuration parameter overrides
-    XMLInputSource in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndImportByName.xml"));
-    AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    ResourceManager resMgr = UIMAFramework.newDefaultResourceManager();
-    File dataPathDir = JUnitExtension.getFile("TextAnalysisEngineImplTest/dataPathDir");
+    // test aggregate with import by name and configuration parameter overrides
+    XMLInputSource in = new XMLInputSource(
+        getFile("TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndImportByName.xml"));
+    AnalysisEngineDescription desc = xmlParser.parseAnalysisEngineDescription(in);
+    ResourceManager resMgr = newDefaultResourceManager();
+    File dataPathDir = getFile("TextAnalysisEngineImplTest/dataPathDir");
     resMgr.setDataPath(dataPathDir.getCanonicalPath());
-    desc.validate(resMgr); 
-    
-    //test invalid aggregate with undefined key in flow
-    in = new XMLInputSource(JUnitExtension
-            .getFile("TextAnalysisEngineImplTest/InvalidAggregate_UndefinedKeyInFlow.xml"));
-    desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-    try {
-      desc.validate();  
-      fail();
-    }
-    catch(ResourceInitializationException e) {
-      //e.printStackTrace();
-      assertEquals(ResourceInitializationException.UNDEFINED_KEY_IN_FLOW, e.getMessageKey());
-      assertNotNull(e.getMessage());
-      assertFalse(e.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED"));
-    }
+    desc.validate(resMgr);
+
+    // test invalid aggregate with undefined key in flow
+    in = new XMLInputSource(
+        getFile("TextAnalysisEngineImplTest/InvalidAggregate_UndefinedKeyInFlow.xml"));
+    AnalysisEngineDescription desc2 = xmlParser.parseAnalysisEngineDescription(in);
+
+    assertThatThrownBy(() -> desc2.validate()) //
+        .isInstanceOf(ResourceInitializationException.class) //
+        .extracting("messageKey", "message") //
+        .satisfies(t -> { //
+          assertThat(t.get(0)).isEqualTo(UNDEFINED_KEY_IN_FLOW); //
+          assertThat((String) t.get(1)).doesNotStartWith("EXCEPTION MESSAGE LOCALIZATION FAILED");
+        });
   }
 
+  @Test
   public void testGetAllComponentSpecifiers() throws Exception {
-    try {
-      Map<String, ResourceSpecifier> allSpecs = aggregateDesc.getAllComponentSpecifiers(null);
-      FlowControllerDescription fcDesc = (FlowControllerDescription) allSpecs
-              .get("TestFlowController");
-      assertNotNull(fcDesc);
-      assertEquals("MyTestFlowController", fcDesc.getMetaData().getName());
-      AnalysisEngineDescription aeDesc = (AnalysisEngineDescription) allSpecs.get("Test");
-      assertNotNull(aeDesc);
-      assertEquals("Test TAE", aeDesc.getMetaData().getName());
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
-    }
+    Map<String, ResourceSpecifier> allSpecs = aggregateDesc.getAllComponentSpecifiers(null);
 
-  }
-  
-  public void testDocumentAnnotationRedefine() {
-    final String tsDescriptor = 
-      "org/apache/uima/analysis_engine/impl/documentAnnotationRedefinitionTS.xml";
-    File file = JUnitExtension.getFile(tsDescriptor);
-    XMLParser parser = UIMAFramework.getXMLParser();
-    boolean resourceInitExc = false;
-    try {
-      TypeSystemDescription tsd = (TypeSystemDescription) parser.parse(new XMLInputSource(file));
-      CasCreationUtils.createCas(tsd, null, new FsIndexDescription[0]);
-    } catch (InvalidXMLException e) {
-      e.printStackTrace();
-      assertTrue(false);
-    } catch (IOException e) {
-      e.printStackTrace();
-      assertTrue(false);
-    } catch (ResourceInitializationException e) {
-      resourceInitExc = true;
-    }
-    assertTrue(resourceInitExc);
+    assertThat((FlowControllerDescription) allSpecs.get("TestFlowController")) //
+        .isNotNull() //
+        .extracting(desc -> desc.getMetaData().getName()).isEqualTo("MyTestFlowController");
+
+    assertThat((AnalysisEngineDescription) allSpecs.get("Test")) //
+        .isNotNull() //
+        .extracting(desc -> desc.getMetaData().getName()).isEqualTo("Test TAE");
   }
 
-  protected void _testInvalidDescriptor(File aFile) throws IOException {
-    assertTrue(aFile.exists());
-    XMLInputSource in = new XMLInputSource(aFile);
-    Exception ex = null;
-    try {
-      AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in);
-      desc.doFullValidation();
-    } catch (InvalidXMLException e) {
-      // e.printStackTrace();
-      ex = e;
-    } catch (ResourceInitializationException e) {
-      // e.printStackTrace();
-      ex = e;
-    }
-    Assert.assertNotNull(ex);
-    Assert.assertNotNull(ex.getMessage());
-    Assert.assertFalse(ex.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED"));
+  @Test
+  public void testDocumentAnnotationRedefine() throws Exception {
+    File file = getFile(
+        "org/apache/uima/analysis_engine/impl/documentAnnotationRedefinitionTS.xml");
+    TypeSystemDescription tsd = xmlParser.parseTypeSystemDescription(new XMLInputSource(file));
+
+    assertThatThrownBy(() -> createCas(tsd, null, new FsIndexDescription[0]))
+        .isInstanceOf(ResourceInitializationException.class);
   }
 
+  @Test
   public void testNoDelegatesToResolve() throws Exception {
     ResourceSpecifierFactory f = UIMAFramework.getResourceSpecifierFactory();
+    
     AnalysisEngineDescription outer = f.createAnalysisEngineDescription();
     AnalysisEngineDescription inner = f.createAnalysisEngineDescription();
     outer.getDelegateAnalysisEngineSpecifiersWithImports().put("inner", inner);
 
-    StringWriter outerXml = new StringWriter();
-    outer.toXML(outerXml);
-    
+    String outerXml = toXmlString(outer);
+
     // Resolving the imports removes the inner AE description
     outer.resolveImports(UIMAFramework.newDefaultResourceManager());
-    
-    StringWriter outerXml2 = new StringWriter();
-    outer.toXML(outerXml2);
 
-    Assert.assertEquals(outerXml.toString(), outerXml2.toString());
+    String outerXml2 = toXmlString(outer);
+
+    assertThat(outerXml2).isEqualTo(outerXml);
+  }
+
+  private void assertDescriptorIsValid(String aPath)
+      throws IOException, InvalidXMLException, ResourceInitializationException {
+    XMLInputSource in = new XMLInputSource(getFile(aPath));
+    AnalysisEngineDescription desc = xmlParser.parseAnalysisEngineDescription(in);
+    desc.doFullValidation();
+  }
+
+  private void assertDescriptorIsNotValid(String aPath) throws IOException {
+    File file = getFile(aPath);
+
+    assertThat(file).exists();
+
+    assertThatThrownBy(
+        () -> xmlParser.parseAnalysisEngineDescription(new XMLInputSource(file)).doFullValidation())
+            .satisfiesAnyOf( //
+                e -> assertThat(e).isInstanceOf(ResourceInitializationException.class), //
+                e -> assertThat(e).isInstanceOf(InvalidXMLException.class)) //
+            .extracting("message", as(InstanceOfAssertFactories.STRING)) //
+            .doesNotStartWith("EXCEPTION MESSAGE LOCALIZATION FAILED");
+  }
+
+  private String toXmlString(XMLizable aObject) throws IOException, SAXException {
+    StringWriter writer = new StringWriter();
+    aObject.toXML(writer);
+    return writer.getBuffer().toString();
   }
 }
diff --git a/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/MetaDataObject_implTest.java b/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/MetaDataObject_implTest.java
index 04cc122..745fd24 100644
--- a/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/MetaDataObject_implTest.java
+++ b/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/MetaDataObject_implTest.java
@@ -16,53 +16,53 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.uima.resource.metadata.impl;
 
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static org.apache.uima.UIMAFramework.getResourceSpecifierFactory;
+import static org.apache.uima.internal.util.SerializationUtils.deserialize;
+import static org.apache.uima.internal.util.SerializationUtils.serialize;
+import static org.assertj.core.api.Assertions.assertThat;
+
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.uima.UIMAFramework;
-import org.apache.uima.internal.util.SerializationUtils;
 import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
 import org.apache.uima.resource.metadata.MetaDataObject;
 import org.apache.uima.resource.metadata.NameValuePair;
-import org.apache.uima.resource.metadata.impl.MetaDataObject_impl.MetaDataAttr;
-import org.apache.uima.test.junit_extension.JUnitExtension;
+import org.apache.uima.test.junit_extension.PrintExceptionsWhenRunFromCommandLineRule;
 import org.apache.uima.util.XMLParser;
+import org.apache.uima.util.XMLizable;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-
-import org.junit.Assert;
-import junit.framework.TestCase;
+import org.xml.sax.SAXException;
 
 /**
  * Tests the MetaDataObject_impl class.
- * 
  */
-public class MetaDataObject_implTest extends TestCase {
+public class MetaDataObject_implTest {
+  public @Rule TestRule exceptingHandlingRule = new PrintExceptionsWhenRunFromCommandLineRule();
 
-  /**
-   * Constructor for MetaDataObject_implTest.
-   * 
-   * @param arg0
-   */
-  public MetaDataObject_implTest(String arg0) {
-    super(arg0);
-  }
+  private TestFruitObject unknownFruit;
+  private TestFruitObject apple1;
+  private TestFruitObject apple2;
+  private TestFruitObject orange;
+  private TestFruitBagObject fruitBag;
 
-  /**
-   * @see TestCase#setUp()
-   */
-  protected void setUp() throws Exception {
-    super.setUp();
+  @Before
+  public void setUp() {
     // create an object that can represent a fruit
     unknownFruit = new TestFruitObject();
   
@@ -72,7 +72,7 @@ public class MetaDataObject_implTest extends TestCase {
     apple1.setAttributeValue("color", "red");
     apple1.setAttributeValue("avgWeightLbs", 0.3F);
     apple1.setAttributeValue("avgCostCents", 40);
-    apple1.setAttributeValue("citrus", Boolean.FALSE);
+    apple1.setAttributeValue("citrus", FALSE);
     apple1.setAttributeValue("commonUses", new String[] { "baking", "snack" });
 
     apple2 = new TestFruitObject();
@@ -80,7 +80,7 @@ public class MetaDataObject_implTest extends TestCase {
     apple2.setAttributeValue("color", "red");
     apple2.setAttributeValue("avgWeightLbs", 0.3F);
     apple2.setAttributeValue("avgCostCents", 40);
-    apple2.setAttributeValue("citrus", Boolean.FALSE);
+    apple2.setAttributeValue("citrus", FALSE);
     apple2.setAttributeValue("commonUses", new String[] { "baking", "snack" });
 
     orange = new TestFruitObject();
@@ -88,7 +88,7 @@ public class MetaDataObject_implTest extends TestCase {
     orange.setAttributeValue("color", "orange");
     orange.setAttributeValue("avgWeightLbs", 0.2F);
     orange.setAttributeValue("avgCostCents", 50);
-    orange.setAttributeValue("citrus", Boolean.TRUE);
+    orange.setAttributeValue("citrus", TRUE);
     orange.setAttributeValue("commonUses", new String[] { "snack", "juice" });
 
     // create a fruit bag containing these three objects
@@ -117,75 +117,57 @@ public class MetaDataObject_implTest extends TestCase {
   /**
    * Test the getAttributes method
    */
+  @Test
   public void testGetAttributes() throws Exception {
-    try {
-      HashSet<MetaDataAttr> apple1Attrs = new HashSet<>(Arrays.asList(apple1.getAttributes()));
-      HashSet<MetaDataAttr> orangeAttrs = new HashSet<>(Arrays.asList(orange.getAttributes()));
-      HashSet<MetaDataAttr> bagAttrs = new HashSet<>(Arrays.asList(fruitBag.getAttributes()));
-      
-      Set<MetaDataAttr> r = TestFruitObject.getMetaDataAttrSet();
-      for (MetaDataAttr r1 : r) {
-        if (!apple1Attrs.contains(r1)) {
-          System.out.println("found bad one");
-        }
-      }
-      System.out.println(r.equals (apple1Attrs));
-      assertEquals(TestFruitObject.getMetaDataAttrSet(), apple1Attrs);
-      assertEquals(TestFruitObject.getMetaDataAttrSet(), orangeAttrs);
-      assertEquals(TestFruitBagObject.getMetaDataAttrSet(), bagAttrs);
-    } catch (RuntimeException e) {
-    JUnitExtension.handleException(e);
-    }
+    assertThat(apple1.getAttributes()).containsAll(TestFruitObject.getMetaDataAttrSet());
+    assertThat(orange.getAttributes()).containsAll(TestFruitObject.getMetaDataAttrSet());
+    assertThat(fruitBag.getAttributes()).containsAll(TestFruitBagObject.getMetaDataAttrSet());
   }
   
   /**
    * Tests the {@link MetaDataObject#equals(Object)} method.
    */
+  @Test
   public void testEquals() throws Exception {
-    try {
-      Assert.assertEquals(unknownFruit, unknownFruit);
-      Assert.assertEquals(apple1, apple2);
-      Assert.assertEquals(apple2, apple1);
-      Assert.assertTrue(!unknownFruit.equals(apple1));
-      Assert.assertTrue(!apple1.equals(orange));
-      Assert.assertTrue(!apple1.equals(null));
-
-      Assert.assertEquals(apple1, apple1.clone());
-      Assert.assertEquals(fruitBag, fruitBag.clone());
-      Assert.assertTrue(!apple1.equals(orange.clone()));
-      
-      // test with maps
-      ConfigurationParameterSettings cps1 = UIMAFramework.getResourceSpecifierFactory().createConfigurationParameterSettings();
-      cps1.getSettingsForGroups().put("k1", new NameValuePair[] {new NameValuePair_impl("s1", "o1")});
-      cps1.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "o2")});
-      ConfigurationParameterSettings cps2 = UIMAFramework.getResourceSpecifierFactory().createConfigurationParameterSettings();
-      cps2.getSettingsForGroups().put("k1", new NameValuePair[] {new NameValuePair_impl("s1", "o1")});
-      cps2.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "o2")});
-      
-      Assert.assertEquals(cps1, cps2);
-      Assert.assertEquals(cps1, cps2.clone());
-      
-      cps2.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "ox2")});
-      Assert.assertFalse(cps1.equals(cps2));
-           
-    } catch (RuntimeException e) {
-      JUnitExtension.handleException(e);
-    }
+    assertThat(unknownFruit).isEqualTo(unknownFruit);
+    assertThat(apple1).isEqualTo(apple2);
+    assertThat(apple2).isEqualTo(apple1);
+    assertThat(unknownFruit).isNotEqualTo(apple1);
+    assertThat(apple1).isNotEqualTo(orange);
+    assertThat(apple1).isNotEqualTo(null);
+
+    assertThat(apple1).isEqualTo(apple1.clone());
+    assertThat(fruitBag).isEqualTo(fruitBag.clone());
+    assertThat(apple1).isNotEqualTo(orange.clone());
+        
+    // test with maps
+    ConfigurationParameterSettings cps1 = getResourceSpecifierFactory().createConfigurationParameterSettings();
+    cps1.getSettingsForGroups().put("k1", new NameValuePair[] {new NameValuePair_impl("s1", "o1")});
+    cps1.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "o2")});
+    
+    ConfigurationParameterSettings cps2 = getResourceSpecifierFactory().createConfigurationParameterSettings();
+    cps2.getSettingsForGroups().put("k1", new NameValuePair[] {new NameValuePair_impl("s1", "o1")});
+    cps2.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "o2")});
+    
+    assertThat(cps1).isEqualTo(cps2);
+    assertThat(cps1).isEqualTo(cps2.clone());
+    
+    cps2.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "ox2")});
+    
+    assertThat(cps1).isNotEqualTo(cps2);
   }
 
   /**
    * Tests the {@link MetaDataObject#toString()} method.
    */
+  @Test
   public void testToString() throws Exception {
-    try {
-      String apple1Str = apple1.toString();
-      String apple2Str = apple2.toString();
-      String orangeStr = orange.toString();
-      Assert.assertEquals(apple1Str, apple2Str);
-      Assert.assertTrue(!apple1Str.equals(orangeStr));
-    } catch (RuntimeException e) {
-      JUnitExtension.handleException(e);
-    }
+    String apple1Str = apple1.toString();
+    String apple2Str = apple2.toString();
+    String orangeStr = orange.toString();
+
+    assertThat(apple1Str).isEqualTo(apple2Str);
+    assertThat(apple1Str).isNotEqualTo(orangeStr);
   }
 
   /**
@@ -194,128 +176,102 @@ public class MetaDataObject_implTest extends TestCase {
    * exercise the {@link MetaDataObject#getAttributeValue(String)} and
    * {@link MetaDataObject#setAttributeValue(String,Object)} methods.
    */
+  @Test
   public void testXMLization() throws Exception {
-    try {
-      // write objects to XML
-
-      StringWriter writer = new StringWriter();
-      apple1.toXML(writer);
-      String apple1xml = writer.getBuffer().toString();
-      // System.out.println(apple1xml);
-
-      writer = new StringWriter();
-      apple2.toXML(writer);
-      String apple2xml = writer.getBuffer().toString();
-
-      writer = new StringWriter();
-      orange.toXML(writer);
-      String orangeXml = writer.getBuffer().toString();
-
-      writer = new StringWriter();
-      fruitBag.toXML(writer);
-      String fruitBagXml = writer.getBuffer().toString();
-
-      // identical objects should have identical XML
-      Assert.assertEquals(apple1xml, apple2xml);
-
-      // parse the XML
-      DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
-      DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
-
-      Document apple1xmlDoc = docBuilder.parse(new ByteArrayInputStream(apple1xml.getBytes()));
-      Document apple2xmlDoc = docBuilder.parse(new ByteArrayInputStream(apple2xml.getBytes()));
-      Document orangeXmlDoc = docBuilder.parse(new ByteArrayInputStream(orangeXml.getBytes()));
-      Document fruitBagXmlDoc = docBuilder.parse(new ByteArrayInputStream(fruitBagXml.getBytes()));
-
-      // construct new objects from the XML
-      XMLParser xmlp = UIMAFramework.getXMLParser();
-      MetaDataObject_impl newApple1 = (MetaDataObject_impl) unknownFruit.clone();
-      newApple1.buildFromXMLElement(apple1xmlDoc.getDocumentElement(), xmlp);
-      MetaDataObject_impl newApple2 = (MetaDataObject_impl) unknownFruit.clone();
-      newApple2.buildFromXMLElement(apple2xmlDoc.getDocumentElement(), xmlp);
-      MetaDataObject_impl newOrange = (MetaDataObject_impl) unknownFruit.clone();
-      newOrange.buildFromXMLElement(orangeXmlDoc.getDocumentElement(), xmlp);
-
-      xmlp.addMapping("fruit", TestFruitObject.class.getName());
-
-      MetaDataObject_impl newFruitBag = new TestFruitBagObject();
-      newFruitBag.buildFromXMLElement(fruitBagXmlDoc.getDocumentElement(), xmlp);
-
-      // new objects should be equal to the originals
-      Assert.assertEquals(apple1, newApple1);
-      Assert.assertEquals(apple2, newApple2);
-      Assert.assertEquals(orange, newOrange);
-      Assert.assertTrue(fruitBag.equals(newFruitBag));
-
-      // test special cases
-
-      // single-property object where property name is omitted from XML
-      String xmlStr = "<fruitBag><fruit><name>banana</name><color>yellow</color></fruit>"
-              + "<fruit><name>raspberry</name><color>red</color></fruit></fruitBag>";
-      Document xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes()));
-      TestFruitBagObject bag = new TestFruitBagObject();
-      bag.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp);
-      TestFruitObject[] fruits = bag.getFruits();
-      Assert.assertEquals(2, fruits.length);
-      Assert.assertEquals("banana", fruits[0].getName());
-      Assert.assertEquals("raspberry", fruits[1].getName());
-
-      // property name omitted but can be inferred from type of value
-      xmlStr = "<fruit><name>banana</name><string>yellow</string></fruit>";
-      xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes()));
-      TestFruitObject banana = new TestFruitObject();
-      banana.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp);
-      Assert.assertEquals("yellow", banana.getColor());
-      Assert.assertEquals("banana", banana.getName());
-
-      // env var reference
-      xmlStr = "<fruit><name>raspberry</name><string><envVarRef>test.raspberry.color</envVarRef></string></fruit>";
-      System.setProperty("test.raspberry.color", "red");
-      xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes()));
-      TestFruitObject raspberry = new TestFruitObject();
-      raspberry.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp);
-      Assert.assertEquals("red", raspberry.getColor());
-      Assert.assertEquals("raspberry", raspberry.getName());
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
-    }
+    // write objects to XML
+    String apple1xml = toXmlString(apple1);
+    String apple2xml = toXmlString(apple2);
+    String orangeXml = toXmlString(orange);
+    String fruitBagXml = toXmlString(fruitBag);
+
+    // identical objects should have identical XML
+    assertThat(apple1xml).isEqualTo(apple2xml);
+
+    // parse the XML
+    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
+    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+
+    Document apple1xmlDoc = docBuilder.parse(new ByteArrayInputStream(apple1xml.getBytes()));
+    Document apple2xmlDoc = docBuilder.parse(new ByteArrayInputStream(apple2xml.getBytes()));
+    Document orangeXmlDoc = docBuilder.parse(new ByteArrayInputStream(orangeXml.getBytes()));
+    Document fruitBagXmlDoc = docBuilder.parse(new ByteArrayInputStream(fruitBagXml.getBytes()));
+
+    // construct new objects from the XML
+    XMLParser xmlp = UIMAFramework.getXMLParser();
+    MetaDataObject_impl newApple1 = (MetaDataObject_impl) unknownFruit.clone();
+    newApple1.buildFromXMLElement(apple1xmlDoc.getDocumentElement(), xmlp);
+    MetaDataObject_impl newApple2 = (MetaDataObject_impl) unknownFruit.clone();
+    newApple2.buildFromXMLElement(apple2xmlDoc.getDocumentElement(), xmlp);
+    MetaDataObject_impl newOrange = (MetaDataObject_impl) unknownFruit.clone();
+    newOrange.buildFromXMLElement(orangeXmlDoc.getDocumentElement(), xmlp);
+
+    xmlp.addMapping("fruit", TestFruitObject.class.getName());
+
+    MetaDataObject_impl newFruitBag = new TestFruitBagObject();
+    newFruitBag.buildFromXMLElement(fruitBagXmlDoc.getDocumentElement(), xmlp);
+
+    // new objects should be equal to the originals
+    Assert.assertEquals(apple1, newApple1);
+    Assert.assertEquals(apple2, newApple2);
+    Assert.assertEquals(orange, newOrange);
+    Assert.assertTrue(fruitBag.equals(newFruitBag));
+
+    // test special cases
+
+    // single-property object where property name is omitted from XML
+    String xmlStr = "<fruitBag><fruit><name>banana</name><color>yellow</color></fruit>"
+            + "<fruit><name>raspberry</name><color>red</color></fruit></fruitBag>";
+    Document xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes()));
+    TestFruitBagObject bag = new TestFruitBagObject();
+    bag.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp);
+    TestFruitObject[] fruits = bag.getFruits();
+    Assert.assertEquals(2, fruits.length);
+    Assert.assertEquals("banana", fruits[0].getName());
+    Assert.assertEquals("raspberry", fruits[1].getName());
+
+    // property name omitted but can be inferred from type of value
+    xmlStr = "<fruit><name>banana</name><string>yellow</string></fruit>";
+    xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes()));
+    TestFruitObject banana = new TestFruitObject();
+    banana.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp);
+    Assert.assertEquals("yellow", banana.getColor());
+    Assert.assertEquals("banana", banana.getName());
+
+    // env var reference
+    xmlStr = "<fruit><name>raspberry</name><string><envVarRef>test.raspberry.color</envVarRef></string></fruit>";
+    System.setProperty("test.raspberry.color", "red");
+    xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes()));
+    TestFruitObject raspberry = new TestFruitObject();
+    raspberry.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp);
+    Assert.assertEquals("red", raspberry.getColor());
+    Assert.assertEquals("raspberry", raspberry.getName());
   }
 
+  @Test
   public void testSerialization() throws Exception {
-    try {
-      byte[] apple1Bytes = SerializationUtils.serialize(apple1);
-      TestFruitObject apple1a = (TestFruitObject) SerializationUtils.deserialize(apple1Bytes);
-      Assert.assertEquals(apple1, apple1a);
-
-      byte[] apple2Bytes = SerializationUtils.serialize(apple2);
-      TestFruitObject apple2a = (TestFruitObject) SerializationUtils.deserialize(apple2Bytes);
-      Assert.assertEquals(apple2, apple2a);
-
-      byte[] orangeBytes = SerializationUtils.serialize(orange);
-      TestFruitObject orange2 = (TestFruitObject) SerializationUtils.deserialize(orangeBytes);
-      Assert.assertEquals(orange, orange2);
-
-      // make sure XMLization still works
-      StringWriter sw = new StringWriter();
-      orange.toXML(sw);
-      String orange1xml = sw.getBuffer().toString();
-      sw.getBuffer().setLength(0);
-      orange2.toXML(sw);
-      String orange2xml = sw.getBuffer().toString();
-      assertEquals(orange1xml, orange2xml);
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
-    }
+    assertThat(deserialize(serialize(apple1)))
+        .isInstanceOf(TestFruitObject.class)
+        .isEqualTo(apple1);
+
+    assertThat(deserialize(serialize(apple2)))
+        .isInstanceOf(TestFruitObject.class)
+        .isEqualTo(apple2);
+
+    byte[] orangeBytes = serialize(orange);
+    assertThat(deserialize(orangeBytes))
+        .isInstanceOf(TestFruitObject.class)
+        .isEqualTo(orange);
+
+    // make sure XMLization still works
+    String orange1xml = toXmlString(orange);
+    String orange2xml = toXmlString((TestFruitObject) deserialize(orangeBytes));
+    
+    assertThat(orange1xml).isEqualTo(orange2xml);
+  }
+  
+  private String toXmlString(XMLizable aObject) throws IOException, SAXException {
+    StringWriter writer = new StringWriter();
+    aObject.toXML(writer);
+    return writer.getBuffer().toString();
   }
-
-  private TestFruitObject unknownFruit;
-
-  private TestFruitObject apple1;
-
-  private TestFruitObject apple2;
-
-  private TestFruitObject orange;
-
-  private TestFruitBagObject fruitBag;
-
 }
diff --git a/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_implTest.java b/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_implTest.java
index 52cbd45..b991c08 100644
--- a/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_implTest.java
+++ b/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_implTest.java
@@ -16,14 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.uima.resource.metadata.impl;
 
+import static java.lang.System.identityHashCode;
+import static java.util.Arrays.asList;
+import static org.apache.uima.UIMAFramework.getResourceSpecifierFactory;
+import static org.apache.uima.UIMAFramework.newDefaultResourceManager;
+import static org.apache.uima.test.junit_extension.JUnitExtension.getFile;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.junit.Assert.assertEquals;
+
 import java.io.File;
 import java.net.URL;
 
-import junit.framework.TestCase;
-
 import org.apache.uima.UIMAFramework;
 import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.resource.ResourceManager;
@@ -32,163 +39,162 @@ import org.apache.uima.resource.metadata.Import;
 import org.apache.uima.resource.metadata.TypeDescription;
 import org.apache.uima.resource.metadata.TypeSystemDescription;
 import org.apache.uima.test.junit_extension.JUnitExtension;
+import org.apache.uima.test.junit_extension.PrintExceptionsWhenRunFromCommandLineRule;
 import org.apache.uima.util.CasCreationUtils;
 import org.apache.uima.util.InvalidXMLException;
 import org.apache.uima.util.XMLInputSource;
+import org.apache.uima.util.XMLParser;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+public class TypeSystemDescription_implTest {
+  public @Rule TestRule exceptingHandlingRule = new PrintExceptionsWhenRunFromCommandLineRule();
+
+  private XMLParser xmlParser;
+
+  @Before
+  public void setUp() throws Exception {
+    xmlParser = UIMAFramework.getXMLParser();
+    xmlParser.enableSchemaValidation(true);
+  }
 
+  @After
+  public void tearDown() throws Exception {
+    // Note that the XML parser is a singleton in the framework, so we have to set this back to the
+    // default.
+    xmlParser.enableSchemaValidation(false);
+  }
 
-public class TypeSystemDescription_implTest extends TestCase {
-
-  /**
-   * Constructor for TypeSystemDescription_implTest.
-   * 
-   * @param arg0
-   */
-  public TypeSystemDescription_implTest(String arg0) {
-    super(arg0);
+  @Test
+  public void testBuildFromXmlElement() throws Exception {
+    File descriptor = getFile("TypeSystemDescriptionImplTest/TestTypeSystem.xml");
+    TypeSystemDescription ts = xmlParser.parseTypeSystemDescription(new XMLInputSource(descriptor));
+
+    assertThat(ts.getName()).isEqualTo("TestTypeSystem");
+    assertThat(ts.getDescription()).isEqualTo("This is a test.");
+    assertThat(ts.getVendor()).isEqualTo("The Apache Software Foundation");
+    assertThat(ts.getVersion()).isEqualTo("0.1");
+
+    assertThat(ts.getImports()).extracting(Import::getName, Import::getLocation).containsExactly(
+        tuple("org.apache.uima.resource.metadata.impl.TypeSystemImportedByName", null),
+        tuple(null, "TypeSystemImportedByLocation.xml"),
+        tuple("TypeSystemImportedFromDataPath", null));
+
+    assertThat(ts.getTypes()).extracting(TypeDescription::getName, TypeDescription::getDescription,
+        TypeDescription::getSupertypeName)
+        .containsExactly(tuple("NamedEntity", "Anything that has a name.", "uima.tcas.Annotation"),
+            tuple("Person", "A person.", "NamedEntity"), tuple("Place", "A place.", "NamedEntity"),
+            tuple("DocumentStructure",
+                "Identifies document structure, such as sentence or paragraph.",
+                "uima.tcas.Annotation"),
+            tuple("Paragraph", "A paragraph.", "DocumentStructure"),
+            tuple("Sentence", "A sentence.", "DocumentStructure"));
+
+    assertThat(ts.getTypes()[4].getFeatures())
+        .extracting(FeatureDescription::getName, FeatureDescription::getDescription,
+            FeatureDescription::getRangeTypeName, FeatureDescription::getElementType,
+            FeatureDescription::getMultipleReferencesAllowed)
+        .containsExactly(
+            tuple("sentences", "Direct references to sentences in this paragraph",
+                "uima.cas.FSArray", "Sentence", false),
+            tuple("testMultiRefAllowedFeature", "A test feature that allows multiple references.",
+                "uima.cas.FSArray", null, true));
   }
 
-  /*
-   * @see TestCase#setUp()
-   */
-  protected void setUp() throws Exception {
-    super.setUp();
-    UIMAFramework.getXMLParser().enableSchemaValidation(true);
+  @Test
+  public void testResolveImports() throws Exception {
+    File descriptor = getFile("TypeSystemDescriptionImplTest/TestTypeSystem.xml");
+    TypeSystemDescription ts = xmlParser.parseTypeSystemDescription(new XMLInputSource(descriptor));
+
+    assertThat(ts.getTypes()).as("Type count before resolving the descriptor").hasSize(6);
+
+    assertThatThrownBy(() -> ts.resolveImports()).isInstanceOf(InvalidXMLException.class);
+    assertThat(ts.getTypes()).as(
+        "Type count after resolving failed should be same as before / no side effect on exception")
+        .hasSize(6);
+
+    // set data path correctly and it should work
+    ResourceManager resMgr = newDefaultResourceManager();
+    resMgr.setDataPath(
+        JUnitExtension.getFile("TypeSystemDescriptionImplTest/dataPathDir").getAbsolutePath());
+    ts.resolveImports(resMgr);
+
+    assertThat(ts.getTypes()).as("Type count after resolving the descriptor").hasSize(13);
   }
 
-  /*
-   * @see TestCase#tearDown()
-   */
-  protected void tearDown() throws Exception {
-    super.tearDown();
+  @Test
+  public void thatCircularImportsDoNotCrash() throws Exception {
+    // test that circular imports don't crash
+    File descriptor = getFile("TypeSystemDescriptionImplTest/Circular1.xml");
+    TypeSystemDescription ts = xmlParser.parseTypeSystemDescription(new XMLInputSource(descriptor));
+    ts.resolveImports();
+    assertEquals(2, ts.getTypes().length);
   }
 
-  public void testBuildFromXmlElement() throws Exception {
-    try {
-      File descriptor = JUnitExtension.getFile("TypeSystemDescriptionImplTest/TestTypeSystem.xml");
-      TypeSystemDescription ts = UIMAFramework.getXMLParser().parseTypeSystemDescription(
-              new XMLInputSource(descriptor));
-
-      assertEquals("TestTypeSystem", ts.getName());
-      assertEquals("This is a test.", ts.getDescription());
-      assertEquals("The Apache Software Foundation", ts.getVendor());
-      assertEquals("0.1", ts.getVersion());
-      Import[] imports = ts.getImports();
-      assertEquals(3, imports.length);
-      assertEquals("org.apache.uima.resource.metadata.impl.TypeSystemImportedByName", imports[0]
-              .getName());
-      assertNull(imports[0].getLocation());
-      assertNull(imports[1].getName());
-      assertEquals("TypeSystemImportedByLocation.xml", imports[1].getLocation());
-
-      TypeDescription[] types = ts.getTypes();
-      assertEquals(6, types.length);
-      TypeDescription paragraphType = types[4];
-      assertEquals("Paragraph", paragraphType.getName());
-      assertEquals("A paragraph.", paragraphType.getDescription());
-      assertEquals("DocumentStructure", paragraphType.getSupertypeName());
-      FeatureDescription[] features = paragraphType.getFeatures();
-      assertEquals(2, features.length);
-      assertEquals("sentences", features[0].getName());
-      assertEquals("Direct references to sentences in this paragraph", features[0].getDescription());
-      assertEquals("uima.cas.FSArray", features[0].getRangeTypeName());
-      assertEquals("Sentence", features[0].getElementType());
-      assertFalse(features[0].getMultipleReferencesAllowed().booleanValue());
-
-      // ts.toXML(System.out);
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
-    }
+  @Test
+  public void thatResolveImportsDoesNothingWhenThereAreNoImports() throws Exception {
+    // calling resolveImports when there are none should do nothing
+    File descriptor = getFile("TypeSystemDescriptionImplTest/TypeSystemImportedByLocation.xml");
+
+    TypeSystemDescription ts = xmlParser.parseTypeSystemDescription(new XMLInputSource(descriptor));
+
+    assertThat(ts.getTypes()).hasSize(2);
+
+    ts.resolveImports();
+
+    assertThat(ts.getTypes()).hasSize(2);
   }
 
-  public void testResolveImports() throws Exception {
-    try {
-      File descriptor = JUnitExtension.getFile("TypeSystemDescriptionImplTest/TestTypeSystem.xml");
-      TypeSystemDescription ts = UIMAFramework.getXMLParser().parseTypeSystemDescription(
-              new XMLInputSource(descriptor));
-
-      TypeDescription[] types = ts.getTypes();
-      assertEquals(6, types.length);
-
-      // resolving imports without setting data path should fail
-      InvalidXMLException ex = null;
-      try {
-        ts.resolveImports();
-      } catch (InvalidXMLException e) {
-        ex = e;
-      }
-      assertNotNull(ex);
-      assertEquals(6, ts.getTypes().length); // should be no side effects when exception is thrown
-
-      // set data path correctly and it should work
-      ResourceManager resMgr = UIMAFramework.newDefaultResourceManager();
-      resMgr.setDataPath(JUnitExtension.getFile("TypeSystemDescriptionImplTest/dataPathDir")
-              .getAbsolutePath());
-      ts.resolveImports(resMgr);
-
-      types = ts.getTypes();
-      assertEquals(13, types.length);
-      
-      // test that circular imports don't crash
-      descriptor = JUnitExtension.getFile("TypeSystemDescriptionImplTest/Circular1.xml");
-      ts = UIMAFramework.getXMLParser().parseTypeSystemDescription(new XMLInputSource(descriptor));
-      ts.resolveImports();
-      assertEquals(2, ts.getTypes().length);
-
-      // calling resolveImports when there are none should do nothing
-      descriptor = JUnitExtension
-              .getFile("TypeSystemDescriptionImplTest/TypeSystemImportedByLocation.xml");
-      ts = UIMAFramework.getXMLParser().parseTypeSystemDescription(new XMLInputSource(descriptor));
-      assertEquals(2, ts.getTypes().length);
-      ts.resolveImports();
-      assertEquals(2, ts.getTypes().length);
-
-      // test import from programatically created TypeSystemDescription
-      TypeSystemDescription typeSystemDescription = UIMAFramework.getResourceSpecifierFactory()
-              .createTypeSystemDescription();
-      Import[] imports = new Import[1];
-      imports[0] = new Import_impl();
-      URL url = JUnitExtension.getFile("TypeSystemDescriptionImplTest").toURL();
-      ((Import_impl) imports[0]).setSourceUrl(url);
-      imports[0].setLocation("TypeSystemImportedByLocation.xml");
-      typeSystemDescription.setImports(imports);
-      TypeSystemDescription typeSystemWithResolvedImports = (TypeSystemDescription) typeSystemDescription
-              .clone();
-      typeSystemWithResolvedImports.resolveImports(resMgr);
-      assertTrue(typeSystemWithResolvedImports.getTypes().length > 0);      
-    
-      //test that importing the same descriptor twice (using the same ResourceManager) caches
-      //the result of the first import and does not create new objects
-      TypeSystemDescription typeSystemDescription2 = UIMAFramework.getResourceSpecifierFactory()
-      .createTypeSystemDescription();
-        Import[] imports2 = new Import[1];
-      imports2[0] = new Import_impl();
-      ((Import_impl) imports2[0]).setSourceUrl(url);
-      imports2[0].setLocation("TypeSystemImportedByLocation.xml");
-      typeSystemDescription2.setImports(imports2);
-      TypeSystemDescription typeSystemWithResolvedImports2 = (TypeSystemDescription) typeSystemDescription2
-              .clone();
-      typeSystemWithResolvedImports2.resolveImports(resMgr);
-      for (int i = 0 ; i < typeSystemWithResolvedImports.getTypes().length; i++) {
-        assertTrue(typeSystemWithResolvedImports.getTypes()[i] == typeSystemWithResolvedImports2.getTypes()[i]);
-      }
-
-    } catch (Exception e) {
-      JUnitExtension.handleException(e);
-    }        
+  @Test
+  public void thatImportFromProgrammaticallyCreatedTypeSystemDescriptionWorks() throws Exception {
+    ResourceManager resMgr = newDefaultResourceManager();
+    URL url = getFile("TypeSystemDescriptionImplTest").toURL();
+
+    // test import from programatically created TypeSystemDescription
+    Import_impl[] imports = { new Import_impl() };
+    imports[0].setSourceUrl(url);
+    imports[0].setLocation("TypeSystemImportedByLocation.xml");
+
+    TypeSystemDescription typeSystemDescription = getResourceSpecifierFactory()
+        .createTypeSystemDescription();
+    typeSystemDescription.setImports(imports);
+    TypeSystemDescription typeSystemWithResolvedImports = (TypeSystemDescription) typeSystemDescription
+        .clone();
+    typeSystemWithResolvedImports.resolveImports(resMgr);
+
+    assertThat(typeSystemWithResolvedImports.getTypes()).isNotEmpty();
+
+    // test that importing the same descriptor twice (using the same ResourceManager) caches
+    // the result of the first import and does not create new objects
+    TypeSystemDescription typeSystemDescription2 = getResourceSpecifierFactory()
+        .createTypeSystemDescription();
+
+    Import_impl[] imports2 = { new Import_impl() };
+    imports2[0].setSourceUrl(url);
+    imports2[0].setLocation("TypeSystemImportedByLocation.xml");
+
+    typeSystemDescription2.setImports(imports2);
+    TypeSystemDescription typeSystemWithResolvedImports2 = (TypeSystemDescription) typeSystemDescription2
+        .clone();
+    typeSystemWithResolvedImports2.resolveImports(resMgr);
+
+    assertThat(typeSystemWithResolvedImports.getTypes())
+        .as("Resolved imports in second type system are the same as in the first (cached)")
+        .usingElementComparator((a, b) -> identityHashCode(a) - identityHashCode(b))
+        .containsExactlyElementsOf(asList(typeSystemWithResolvedImports2.getTypes()));
   }
 
+  @Test
   public void testInvalidTypeSystem() throws Exception {
-    File file = JUnitExtension.getFile("TypeSystemDescriptionImplTest/InvalidTypeSystem1.xml");
-    TypeSystemDescription tsDesc = UIMAFramework.getXMLParser().parseTypeSystemDescription(
-            new XMLInputSource(file));
-    try {
-      CasCreationUtils.createCas(tsDesc, null, null);
-      // the above line should throw an exception
-      fail();
-    } catch (ResourceInitializationException e) {
-      assertNotNull(e.getMessage());
-      assertFalse(e.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED"));
-    }
+    File file = getFile("TypeSystemDescriptionImplTest/InvalidTypeSystem1.xml");
+
+    TypeSystemDescription tsDesc = xmlParser.parseTypeSystemDescription(new XMLInputSource(file));
+
+    assertThatThrownBy(() -> CasCreationUtils.createCas(tsDesc, null, null))
+        .isInstanceOf(ResourceInitializationException.class)
+        .hasMessageContaining("uima.cas.String");
   }
 }
diff --git a/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/PrintExceptionsWhenRunFromCommandLineRule.java b/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/PrintExceptionsWhenRunFromCommandLineRule.java
new file mode 100644
index 0000000..edd2932
--- /dev/null
+++ b/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/PrintExceptionsWhenRunFromCommandLineRule.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.test.junit_extension;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+public class PrintExceptionsWhenRunFromCommandLineRule
+    implements TestRule
+{
+
+    @Override
+    public Statement apply(Statement aBase, Description aDescription)
+    {
+        return new Statement()
+        {
+            @Override
+            public void evaluate() throws Throwable
+            {
+                try {
+                    aBase.evaluate();
+                }
+                catch (Exception e) {
+                    JUnitExtension.handleException(e);
+                }
+            }
+        };
+    }
+}