diff --git a/asterixdb/asterix-om/pom.xml b/asterixdb/asterix-om/pom.xml
index b2beb41..f536be1 100644
--- a/asterixdb/asterix-om/pom.xml
+++ b/asterixdb/asterix-om/pom.xml
@@ -129,5 +129,10 @@
       <artifactId>jaxb-api</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java
deleted file mode 100644
index 29cb9a7..0000000
--- a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *  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.asterix.om.typecomputer;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-import org.junit.Assert;
-import org.junit.Test;
-import org.reflections.Reflections;
-import org.reflections.scanners.SubTypesScanner;
-
-public class ExceptionTest {
-
-    @Test
-    public void test() throws Exception {
-        // Tests all usual type computers.
-        Reflections reflections = new Reflections("org.apache.asterix.om.typecomputer", new SubTypesScanner(false));
-        Set<Class<? extends IResultTypeComputer>> classes = reflections.getSubTypesOf(IResultTypeComputer.class);
-        int numTypeComputers = 0;
-        for (Class<? extends IResultTypeComputer> c : classes) {
-            if (Modifier.isAbstract(c.getModifiers())) {
-                continue;
-            }
-            testTypeComputer(c);
-            ++numTypeComputers;
-        }
-        // Currently, there are 83 type computers.
-        Assert.assertTrue(numTypeComputers >= 83);
-    }
-
-    private void testTypeComputer(Class<? extends IResultTypeComputer> c) throws Exception {
-        // Mocks the type environment.
-        IVariableTypeEnvironment mockTypeEnv = mock(IVariableTypeEnvironment.class);
-        // Mocks the metadata provider.
-        IMetadataProvider<?, ?> mockMetadataProvider = mock(IMetadataProvider.class);
-
-        // Mocks function expression.
-        AbstractFunctionCallExpression mockExpr = mock(AbstractFunctionCallExpression.class);
-        FunctionIdentifier fid = mock(FunctionIdentifier.class);
-        when(mockExpr.getFunctionIdentifier()).thenReturn(fid);
-        when(fid.getName()).thenReturn("testFunction");
-
-        int numCombination = (int) Math.pow(ATypeTag.values().length, 2);
-        // Sets two arguments for the mocked function expression.
-        for (int index = 0; index < numCombination; ++index) {
-            try {
-                List<Mutable<ILogicalExpression>> argRefs = new ArrayList<>();
-                for (int argIndex = 0; argIndex < 2; ++argIndex) {
-                    int base = (int) Math.pow(ATypeTag.values().length, argIndex);
-                    ILogicalExpression mockArg = mock(ILogicalExpression.class);
-                    argRefs.add(new MutableObject<>(mockArg));
-                    IAType mockType = mock(IAType.class);
-                    when(mockTypeEnv.getType(mockArg)).thenReturn(mockType);
-                    int serializedTypeTag = (index / base) % ATypeTag.values().length + 1;
-                    ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[serializedTypeTag];
-                    if (typeTag == null) {
-                        // For some reason, type tag 39 does not exist.
-                        typeTag = ATypeTag.ANY;
-                    }
-                    when(mockType.getTypeTag()).thenReturn(typeTag);
-                }
-
-                // Sets up arguments for the mocked expression.
-                when(mockExpr.getArguments()).thenReturn(argRefs);
-
-                // Sets up required/actual types of the mocked expression.
-                Object[] opaqueParameters = new Object[2];
-                opaqueParameters[0] = BuiltinType.ANY;
-                opaqueParameters[1] = BuiltinType.ANY;
-                when(mockExpr.getOpaqueParameters()).thenReturn(opaqueParameters);
-
-                // Invokes a type computer.
-                IResultTypeComputer instance;
-                Field[] fields = c.getFields();
-                for (Field field : fields) {
-                    if (field.getName().startsWith("INSTANCE")) {
-                        instance = (IResultTypeComputer) field.get(null);
-                        instance.computeType(mockExpr, mockTypeEnv, mockMetadataProvider);
-                    }
-                }
-            } catch (AlgebricksException ae) {
-                String msg = ae.getMessage();
-                if (msg.startsWith("ASX")) {
-                    // Verifies the error code.
-                    int errorCode = Integer.parseInt(msg.substring(3, 7));
-                    Assert.assertTrue(errorCode >= 1000 && errorCode < 2000);
-                    continue;
-                } else {
-                    // Any root-level compilation exceptions thrown from type computers should have an error code.
-                    Assert.assertTrue(!(ae instanceof AlgebricksException) || (ae.getCause() != null));
-                }
-            } catch (ClassCastException e) {
-                continue;
-            }
-        }
-    }
-}
diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
deleted file mode 100644
index 5f5af65..0000000
--- a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.asterix.om.typecomputer;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.AUnionType;
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-import org.junit.Assert;
-import org.junit.Test;
-import org.reflections.Reflections;
-import org.reflections.scanners.SubTypesScanner;
-
-// Tests if all type computers can handle input type ANY properly.
-// TODO: this test should be fixed/updated/modified/enhanced
-public class TypeComputerTest {
-
-    @Test
-    public void test() throws Exception {
-        // Mocks the type environment.
-        IVariableTypeEnvironment mockTypeEnv = mock(IVariableTypeEnvironment.class);
-
-        // Mocks the metadata provider.
-        IMetadataProvider<?, ?> mockMetadataProvider = mock(IMetadataProvider.class);
-
-        // Mocks function expression.
-        AbstractFunctionCallExpression mockExpr = mock(AbstractFunctionCallExpression.class);
-        FunctionIdentifier fid = mock(FunctionIdentifier.class);
-        when(mockExpr.getFunctionIdentifier()).thenReturn(fid);
-        when(fid.getName()).thenReturn("testFunction");
-
-        // A function at most has six argument.
-        List<Mutable<ILogicalExpression>> sixArgs = createArgs(6, mockTypeEnv);
-
-        // Sets up arguments for the mocked expression.
-        when(mockExpr.getArguments()).thenReturn(sixArgs);
-
-        // Sets up required/actual types of the mocked expression.
-        Object[] opaqueParameters = new Object[2];
-        opaqueParameters[0] = BuiltinType.ANY;
-        opaqueParameters[1] = BuiltinType.ANY;
-        when(mockExpr.getOpaqueParameters()).thenReturn(opaqueParameters);
-
-        // functions that check the number of args inside the type computer
-        List<Mutable<ILogicalExpression>> replaceArgs = createArgs(4, mockTypeEnv);
-        List<Mutable<ILogicalExpression>> sliceArgs = createArgs(3, mockTypeEnv);
-        List<Mutable<ILogicalExpression>> rangeArgs = createArgs(3, mockTypeEnv);
-        HashMap<String, List<Mutable<ILogicalExpression>>> map = new HashMap<>();
-        map.put("INSTANCE_REPLACE", replaceArgs);
-        map.put("INSTANCE_SLICE", sliceArgs);
-        map.put("ArrayRangeTypeComputer", rangeArgs);
-
-        // Several exceptional type computers.
-        Set<String> exceptionalTypeComputers = new HashSet<>();
-        exceptionalTypeComputers.add("InjectFailureTypeComputer");
-        exceptionalTypeComputers.add("RecordAddFieldsTypeComputer");
-        exceptionalTypeComputers.add("OpenRecordConstructorResultType");
-        exceptionalTypeComputers.add("RecordRemoveFieldsTypeComputer");
-        exceptionalTypeComputers.add("ClosedRecordConstructorResultType");
-        exceptionalTypeComputers.add("LocalAvgTypeComputer");
-        exceptionalTypeComputers.add("BooleanOnlyTypeComputer");
-        exceptionalTypeComputers.add("AMissingTypeComputer");
-        exceptionalTypeComputers.add("NullableDoubleTypeComputer");
-        exceptionalTypeComputers.add("RecordMergeTypeComputer");
-        exceptionalTypeComputers.add("BooleanOrMissingTypeComputer");
-        exceptionalTypeComputers.add("LocalSingleVarStatisticsTypeComputer");
-        exceptionalTypeComputers.add("ScalarArrayAggTypeComputer");
-
-        // Tests all usual type computers.
-        Reflections reflections = new Reflections("org.apache.asterix.om.typecomputer", new SubTypesScanner(false));
-        Set<Class<? extends IResultTypeComputer>> classes = reflections.getSubTypesOf(IResultTypeComputer.class);
-        for (Class<? extends IResultTypeComputer> c : classes) {
-            if (exceptionalTypeComputers.contains(c.getSimpleName()) || Modifier.isAbstract(c.getModifiers())) {
-                continue;
-            }
-            System.out.println("Test type computer: " + c.getName());
-            Assert.assertTrue(testTypeComputer(c, mockTypeEnv, mockMetadataProvider, mockExpr, map, sixArgs));
-        }
-    }
-
-    private boolean testTypeComputer(Class<? extends IResultTypeComputer> c, IVariableTypeEnvironment mockTypeEnv,
-            IMetadataProvider<?, ?> mockMetadataProvider, AbstractFunctionCallExpression mockExpr,
-            HashMap<String, List<Mutable<ILogicalExpression>>> map, List<Mutable<ILogicalExpression>> sixArgs)
-            throws Exception {
-        // Tests the return type. It should be either ANY or NULLABLE/MISSABLE.
-        IResultTypeComputer instance;
-        IAType resultType;
-        Field[] fields = c.getFields();
-        List<Mutable<ILogicalExpression>> args;
-        for (Field field : fields) {
-            if (field.getName().startsWith("INSTANCE")) {
-                System.out.println("Test type computer INSTANCE: " + field.getName());
-                args = getArgs(field.getName(), c, map);
-                if (args != null) {
-                    when(mockExpr.getArguments()).thenReturn(args);
-                } else {
-                    when(mockExpr.getArguments()).thenReturn(sixArgs);
-                }
-                instance = (IResultTypeComputer) field.get(null);
-                resultType = instance.computeType(mockExpr, mockTypeEnv, mockMetadataProvider);
-                ATypeTag typeTag = resultType.getTypeTag();
-                if (typeTag != ATypeTag.ANY && !(typeTag == ATypeTag.UNION && ((AUnionType) resultType).isNullableType()
-                        && ((AUnionType) resultType).isMissableType())) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    private List<Mutable<ILogicalExpression>> createArgs(int numArgs, IVariableTypeEnvironment mockTypeEnv)
-            throws Exception {
-        List<Mutable<ILogicalExpression>> argRefs = new ArrayList<>();
-        for (int argIndex = 0; argIndex < numArgs; ++argIndex) {
-            ILogicalExpression mockArg = mock(ILogicalExpression.class);
-            argRefs.add(new MutableObject<>(mockArg));
-            when(mockTypeEnv.getType(mockArg)).thenReturn(BuiltinType.ANY);
-        }
-
-        return argRefs;
-    }
-
-    private List<Mutable<ILogicalExpression>> getArgs(String instanceName, Class<? extends IResultTypeComputer> c,
-            HashMap<String, List<Mutable<ILogicalExpression>>> map) {
-        if (instanceName.equals("INSTANCE")) {
-            return map.get(c.getSimpleName());
-        } else {
-            return map.get(instanceName);
-        }
-    }
-}
diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
new file mode 100644
index 0000000..d0ffdb9
--- /dev/null
+++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
@@ -0,0 +1,183 @@
+/*
+ *  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.asterix.test.om.typecomputer;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.reflections.Reflections;
+import org.reflections.scanners.SubTypesScanner;
+
+/**
+ * This test passes all possible combinations of types to each type computer, to ensure each type computer handles
+ * them properly, and in case of an exception, the exception falls within the defined exception codes.
+ *
+ * Care needs to be taken when deciding the number of arguments, below is how the tests are calculated:
+ * The number of combinations is = n ^ m
+ * n = number of arguments
+ * m = number of types available
+ *
+ * Example:
+ * 2 arguments, 40 types = 1600 combinations per type computer
+ * 3 arguments, 40 types = 64000 combinations per type computer
+ */
+
+@RunWith(Parameterized.class)
+public class ExceptionTest {
+
+    private static final Logger LOGGER = LogManager.getLogger();
+
+    // Number of arguments to be passed. Number of combinations depends on number of arguments
+    private static int numberOfArguments = 2;
+    private static int numberOfCombinations = (int) Math.pow(ATypeTag.values().length, numberOfArguments);
+
+    // Test parameters
+    @Parameter
+    public String testName;
+
+    @Parameter(1)
+    public Class<? extends IResultTypeComputer> clazz;
+
+    @Parameters(name = "TypeComputerTest {index}: {0}")
+    public static Collection<Object[]> tests() {
+
+        // Prepare tests
+        List<Object[]> tests = new ArrayList<>();
+
+        // Tests all usual type computers.
+        Reflections reflections = new Reflections("org.apache.asterix.om.typecomputer", new SubTypesScanner(false));
+        Set<Class<? extends IResultTypeComputer>> classes = reflections.getSubTypesOf(IResultTypeComputer.class);
+
+        for (Class<? extends IResultTypeComputer> clazz : classes) {
+            if (Modifier.isAbstract(clazz.getModifiers())) {
+                LOGGER.log(Level.INFO, "Excluding " + clazz.getSimpleName() + " (Abstract class)");
+                continue;
+            }
+
+            tests.add(new Object[] { clazz.getSimpleName(), clazz });
+        }
+
+        return tests;
+    }
+
+    @Test
+    public void test() throws Exception {
+
+        // Arguments list
+        Object[] opaqueParameters = new Object[] { BuiltinType.ANY, BuiltinType.ANY };
+        List<Mutable<ILogicalExpression>> argumentsList = new ArrayList<>(numberOfArguments);
+
+        // Sets arguments for the mocked function expression.
+        for (int index = 0; index < numberOfCombinations; ++index) {
+
+            argumentsList.clear();
+
+            // Type environment and metadata provider
+            IVariableTypeEnvironment typeEnv = mock(IVariableTypeEnvironment.class);
+            IMetadataProvider metadataProvider = mock(IMetadataProvider.class);
+
+            // Function identifier
+            FunctionIdentifier functionIdentifier = mock(FunctionIdentifier.class);
+            when(functionIdentifier.getName()).thenReturn("testFunction");
+
+            // Function call expression
+            AbstractFunctionCallExpression functionCallExpression = mock(AbstractFunctionCallExpression.class);
+            when(functionCallExpression.getFunctionIdentifier()).thenReturn(functionIdentifier);
+
+            try {
+                for (int argIndex = 0; argIndex < numberOfArguments; ++argIndex) {
+                    int base = (int) Math.pow(ATypeTag.values().length, argIndex);
+                    int serializedTypeTag = (index / base) % ATypeTag.values().length + 1;
+
+                    ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[serializedTypeTag];
+                    if (typeTag == null) {
+                        // If any tags have been removed or are missing, replace them with any
+                        typeTag = ATypeTag.ANY;
+                    }
+
+                    // Set the types
+                    IAType iaType = mock(IAType.class);
+                    when(iaType.getTypeTag()).thenReturn(typeTag);
+
+                    ILogicalExpression argument = mock(ILogicalExpression.class);
+                    when(typeEnv.getType(argument)).thenReturn(iaType);
+
+                    // Add argument to the arguments list
+                    argumentsList.add(new MutableObject<>(argument));
+                }
+
+                // Sets up arguments for the mocked expression.
+                when(functionCallExpression.getArguments()).thenReturn(argumentsList);
+                when(functionCallExpression.getOpaqueParameters()).thenReturn(opaqueParameters);
+
+                // Invokes a type computer.
+                IResultTypeComputer instance;
+                Field[] fields = clazz.getFields();
+
+                for (Field field : fields) {
+                    if (field.getType().equals(clazz)) {
+                        instance = (IResultTypeComputer) field.get(null);
+                        instance.computeType(functionCallExpression, typeEnv, metadataProvider);
+                    }
+                }
+            } catch (AlgebricksException ae) {
+                String msg = ae.getMessage();
+                if (msg.startsWith("ASX")) {
+                    // Verifies the error code.
+                    int errorCode = Integer.parseInt(msg.substring(3, 7));
+                    Assert.assertTrue(errorCode >= 1000 && errorCode < 2000);
+                } else {
+                    // Any root-level compilation exceptions thrown from type computers should have an error code.
+                    Assert.assertTrue((ae.getCause() != null));
+                }
+            } catch (ClassCastException e) {
+                // Do nothing
+            }
+        }
+    }
+}
diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/TypeComputerTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/TypeComputerTest.java
new file mode 100644
index 0000000..9f6724e
--- /dev/null
+++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/TypeComputerTest.java
@@ -0,0 +1,275 @@
+/*
+ * 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.asterix.test.om.typecomputer;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.reflections.Reflections;
+import org.reflections.scanners.SubTypesScanner;
+
+/**
+ * This test passes a number of arguments to the type computers, all arguments of type "any", and ensures that
+ * each computer handles the "any" type properly. The expected behavior for each type computer is to return "any",
+ * "nullable" or "missable" type result.
+ *
+ * Things to note:
+ * - The function passes 6 "any" arguments because, as of now, no function that we have has more than 6 arguments.
+ * two other lists are made (3 args and 4 args), those are needed by specific type computers for now, those should be
+ * changed and then the lists can be removed from the test.
+ * - Some functions have a different behavior with "any" value, those will be added to an exception list.
+ * - Some functions check their arguments count, this will make passing 6 arguments fail,
+ * those are added to exception list.
+ */
+
+@RunWith(Parameterized.class)
+public class TypeComputerTest {
+
+    private static final Logger LOGGER = LogManager.getLogger();
+
+    // type computers that have a different behavior when handling "any" type
+    private static Set<String> differentBehaviorFunctions = new HashSet<>();
+
+    // TODO(Hussain) Remove this after the type computers have been updated
+    // type computers that check the number of arguments
+    private static HashMap<Field, List<Mutable<ILogicalExpression>>> checkArgsCountFunctions = new HashMap<>();
+
+    // Test parameters
+    @Parameter
+    public String testName;
+
+    @Parameter(1)
+    public Class<? extends IResultTypeComputer> clazz;
+
+    @Parameters(name = "TypeComputerTest {index}: {0}")
+    public static Collection<Object[]> tests() {
+
+        // Do any needed preparations once
+        prepare();
+
+        // Prepare tests
+        List<Object[]> tests = new ArrayList<>();
+
+        // Tests all usual type computers.
+        Reflections reflections = new Reflections("org.apache.asterix.om.typecomputer", new SubTypesScanner(false));
+        Set<Class<? extends IResultTypeComputer>> classes = reflections.getSubTypesOf(IResultTypeComputer.class);
+
+        for (Class<? extends IResultTypeComputer> clazz : classes) {
+            if (Modifier.isAbstract(clazz.getModifiers())) {
+                LOGGER.log(Level.INFO, "Excluding " + clazz.getSimpleName() + " (Abstract class)");
+                continue;
+            }
+
+            if (differentBehaviorFunctions.contains(clazz.getSimpleName())) {
+                LOGGER.log(Level.INFO, "Excluding " + clazz.getSimpleName() + " (Special behavior)");
+                continue;
+            }
+
+            tests.add(new Object[] { clazz.getSimpleName(), clazz });
+        }
+
+        return tests;
+    }
+
+    /**
+     * Test return types should be either "any", "missable" or "nullable"
+     *
+     * @throws Exception Exception
+     */
+    @Test
+    public void test() throws Exception {
+
+        // Type environment and metadata provider
+        IVariableTypeEnvironment typeEnv = mock(IVariableTypeEnvironment.class);
+        IMetadataProvider metadataProvider = mock(IMetadataProvider.class);
+
+        // Arguments all of type "any"
+        List<Mutable<ILogicalExpression>> threeArgs = createArgs(3, typeEnv);
+        List<Mutable<ILogicalExpression>> fourArgs = createArgs(4, typeEnv);
+        List<Mutable<ILogicalExpression>> sixArgs = createArgs(6, typeEnv);
+
+        // TODO(Hussain) Remove this after the type computers are updated
+        // Add to exception list for computers checking their arguments count
+        addComputersCheckingArgsCount(threeArgs, fourArgs);
+
+        // Mocks function identifier
+        FunctionIdentifier functionIdentifier = mock(FunctionIdentifier.class);
+        when(functionIdentifier.getName()).thenReturn("testFunction");
+
+        // Mocks function expression.
+        AbstractFunctionCallExpression functionCallExpression = mock(AbstractFunctionCallExpression.class);
+        when(functionCallExpression.getFunctionIdentifier()).thenReturn(functionIdentifier);
+
+        // Sets up required/actual types of the mocked expression.
+        Object[] opaqueParameters = new Object[] { BuiltinType.ANY, BuiltinType.ANY };
+        when(functionCallExpression.getOpaqueParameters()).thenReturn(opaqueParameters);
+
+        // Tests the return type. It should be either ANY or NULLABLE/MISSABLE.
+        IResultTypeComputer instance;
+        IAType resultType;
+        List<Mutable<ILogicalExpression>> args;
+        Field[] fields = clazz.getFields();
+
+        for (Field field : fields) {
+
+            // Ensure the field is one of the instances of the class
+            if (field.getType().equals(clazz)) {
+                LOGGER.log(Level.INFO, "Testing " + clazz.getSimpleName() + ": " + field.getName());
+
+                // Need to check if this is a special type computer that counts number of arguments
+                args = checkArgsCountFunctions.get(field);
+
+                // Yes, pass its specified arguments in the map
+                if (args != null) {
+                    when(functionCallExpression.getArguments()).thenReturn(args);
+                }
+                // No, pass six arguments
+                else {
+                    when(functionCallExpression.getArguments()).thenReturn(sixArgs);
+                }
+
+                instance = (IResultTypeComputer) field.get(null);
+                resultType = instance.computeType(functionCallExpression, typeEnv, metadataProvider);
+                ATypeTag typeTag = resultType.getTypeTag();
+
+                // Result should be ANY, Missable or Nullable
+                Assert.assertTrue(typeTag == ATypeTag.ANY
+                        || (typeTag == ATypeTag.UNION && ((AUnionType) resultType).isNullableType()
+                                || ((AUnionType) resultType).isMissableType()));
+            }
+        }
+    }
+
+    public static void prepare() {
+
+        // Add to exception list for computers having a different behavior for "any" type
+        addComputersBehavingDifferently();
+    }
+
+    // TODO This is not a good practice, if the class name is changed, the test will fail and this needs to be updated
+    // Consider using annotation to avoid modifying the test and have a generic behavior
+    /**
+     * Adds the type computers that have a different behavior for "any" type.
+     */
+    private static void addComputersBehavingDifferently() {
+        differentBehaviorFunctions.add("InjectFailureTypeComputer");
+        differentBehaviorFunctions.add("RecordAddFieldsTypeComputer");
+        differentBehaviorFunctions.add("OpenRecordConstructorResultType");
+        differentBehaviorFunctions.add("RecordRemoveFieldsTypeComputer");
+        differentBehaviorFunctions.add("ClosedRecordConstructorResultType");
+        differentBehaviorFunctions.add("LocalAvgTypeComputer");
+        differentBehaviorFunctions.add("BooleanOnlyTypeComputer");
+        differentBehaviorFunctions.add("AMissingTypeComputer");
+        differentBehaviorFunctions.add("NullableDoubleTypeComputer");
+        differentBehaviorFunctions.add("RecordMergeTypeComputer");
+        differentBehaviorFunctions.add("BooleanOrMissingTypeComputer");
+        differentBehaviorFunctions.add("LocalSingleVarStatisticsTypeComputer");
+    }
+
+    // TODO(Hussain) Remove this after the type computers are updated
+    /**
+     * Adds the type computers that check the args count in their method body. If 6 arguments are passed to those
+     * computers, they're gonna throw an exception, so we manually specify how many arguments they should get.
+     *
+     * @throws Exception Exception
+     */
+    private static void addComputersCheckingArgsCount(List<Mutable<ILogicalExpression>> threeArgs,
+            List<Mutable<ILogicalExpression>> fourArgs) throws Exception {
+
+        // AListTypeComputer
+        Class<?> clazz = Class.forName("org.apache.asterix.om.typecomputer.impl.AListTypeComputer");
+        Field[] fields = clazz.getFields();
+
+        for (Field field : fields) {
+            if (field.getName().equalsIgnoreCase("INSTANCE_SLICE")) {
+                LOGGER.log(Level.INFO, field.getName() + " will use only 3 arguments");
+                checkArgsCountFunctions.put(field, threeArgs);
+            }
+
+            if (field.getName().equalsIgnoreCase("INSTANCE_REPLACE")) {
+                LOGGER.log(Level.INFO, field.getName() + " will use only 4 arguments");
+                checkArgsCountFunctions.put(field, fourArgs);
+            }
+        }
+
+        // ArrayRangeTypeComputer
+        clazz = Class.forName("org.apache.asterix.om.typecomputer.impl.ArrayRangeTypeComputer");
+        fields = clazz.getFields();
+
+        for (Field field : fields) {
+            if (field.getName().equalsIgnoreCase("INSTANCE")) {
+                LOGGER.log(Level.INFO, field.getName() + " will use only 3 arguments");
+                checkArgsCountFunctions.put(field, threeArgs);
+            }
+        }
+    }
+
+    /**
+     * Creates expressions matching the number passed as an argument. Variable type environment is set for all those
+     * expressions to be of type "any".
+     *
+     * @param numArgs number of arguments to create
+     * @return a list holding the created expressions
+     * @throws Exception Exception
+     */
+    private static List<Mutable<ILogicalExpression>> createArgs(int numArgs, IVariableTypeEnvironment typeEnv)
+            throws Exception {
+
+        List<Mutable<ILogicalExpression>> arguments = new ArrayList<>();
+
+        for (int i = 0; i < numArgs; ++i) {
+            ILogicalExpression argument = mock(ILogicalExpression.class);
+            arguments.add(new MutableObject<>(argument));
+            when(typeEnv.getType(argument)).thenReturn(BuiltinType.ANY);
+        }
+
+        return arguments;
+    }
+}
diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/util/JSONDeserializerForTypesTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/util/JSONDeserializerForTypesTest.java
similarity index 98%
rename from asterixdb/asterix-om/src/test/java/org/apache/asterix/om/util/JSONDeserializerForTypesTest.java
rename to asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/util/JSONDeserializerForTypesTest.java
index 32ec75a..35e4d35 100644
--- a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/util/JSONDeserializerForTypesTest.java
+++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/util/JSONDeserializerForTypesTest.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.asterix.om.util;
+package org.apache.asterix.test.om.util;
 
 import java.util.ArrayList;
 import java.util.List;
