diff --git a/.idea/runConfigurations/run_tests.xml b/.idea/runConfigurations/run_tests.xml
index ea56f5fb0..cc23b742d 100644
--- a/.idea/runConfigurations/run_tests.xml
+++ b/.idea/runConfigurations/run_tests.xml
@@ -13,7 +13,7 @@
     <option name="MAIN_CLASS_NAME" value="" />
     <option name="METHOD_NAME" value="" />
     <option name="TEST_OBJECT" value="package" />
-    <option name="VM_PARAMETERS" value="-ea -Dteavm.junit.target=target/js-tests -Dteavm.junit.js.runner=htmlunit -Dteavm.junit.js.threads=2" />
+    <option name="VM_PARAMETERS" value="-ea -Dteavm.junit.target=target/js-tests -Dteavm.junit.js.runner=htmlunit -Dteavm.junit.js.threads=1 -Dteavm.junit.minified=true -Dteavm.junit.optimized=true" />
     <option name="PARAMETERS" value="" />
     <option name="WORKING_DIRECTORY" value="file://$MODULE_DIR$" />
     <option name="ENV_VARIABLES" />
@@ -22,7 +22,7 @@
       <value defaultName="singleModule" />
     </option>
     <envs />
-    <dir value="$PROJECT_DIR$/../../idea-debug/teavm/tests/src/test/java" />
+    <dir value="$USER_HOME$/idea-debug/teavm/tests/src/test/java" />
     <patterns />
     <method />
   </configuration>
diff --git a/.travis.yml b/.travis.yml
index 999c9e059..1de572b60 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,8 @@ script: >
   mvn -e test \
    -Dteavm.junit.target=target/js-tests \
    -Dteavm.junit.js.runner=htmlunit \
-   -Dteavm.junit.js.threads=1
+   -Dteavm.junit.js.threads=1 \
+   -Dteavm.junit.optimized=true \
+   -Dteavm.junit.minified=true
 after_script:
   - rm -rf $HOME/.m2/repository/org/teavm
\ No newline at end of file
diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java b/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java
index f14be7d5c..226925e95 100644
--- a/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java
+++ b/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java
@@ -16,8 +16,8 @@
 package org.teavm.backend.javascript.rendering;
 
 public final class RenderingUtil {
-    public static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
-    public static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    private static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
+    private static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
     private RenderingUtil() {
     }
@@ -75,10 +75,11 @@ public final class RenderingUtil {
 
     public static String indexToId(int index) {
         StringBuilder sb = new StringBuilder();
-        do {
+        sb.append(variableNames.charAt(index % variableNames.length()));
+        while (index > 0) {
             sb.append(variablePartNames.charAt(index % variablePartNames.length()));
             index /= variablePartNames.length();
-        } while (index > 0);
+        }
         return sb.toString();
     }
 }
diff --git a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestConfiguration.java b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestConfiguration.java
new file mode 100644
index 000000000..98c0731ee
--- /dev/null
+++ b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestConfiguration.java
@@ -0,0 +1,79 @@
+/*
+ *  Copyright 2016 Alexey Andreev.
+ *
+ *  Licensed 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.teavm.junit;
+
+import org.teavm.backend.javascript.JavaScriptTarget;
+import org.teavm.vm.TeaVM;
+import org.teavm.vm.TeaVMOptimizationLevel;
+
+interface TeaVMTestConfiguration {
+    String getSuffix();
+
+    void apply(TeaVM vm);
+
+    void apply(JavaScriptTarget target);
+
+    TeaVMTestConfiguration DEFAULT = new TeaVMTestConfiguration() {
+        @Override
+        public String getSuffix() {
+            return "";
+        }
+
+        @Override
+        public void apply(TeaVM vm) {
+            vm.setOptimizationLevel(TeaVMOptimizationLevel.SIMPLE);
+        }
+
+        @Override
+        public void apply(JavaScriptTarget target) {
+            target.setMinifying(false);
+        }
+    };
+
+    TeaVMTestConfiguration OPTIMIZED = new TeaVMTestConfiguration() {
+        @Override
+        public String getSuffix() {
+            return "optimized";
+        }
+
+        @Override
+        public void apply(TeaVM vm) {
+            vm.setOptimizationLevel(TeaVMOptimizationLevel.FULL);
+        }
+
+        @Override
+        public void apply(JavaScriptTarget target) {
+            target.setMinifying(false);
+        }
+    };
+
+    TeaVMTestConfiguration MINIFIED = new TeaVMTestConfiguration() {
+        @Override
+        public String getSuffix() {
+            return "min";
+        }
+
+        @Override
+        public void apply(TeaVM vm) {
+            vm.setOptimizationLevel(TeaVMOptimizationLevel.SIMPLE);
+        }
+
+        @Override
+        public void apply(JavaScriptTarget target) {
+            target.setMinifying(true);
+        }
+    };
+}
diff --git a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java
index acb8f5e8b..6a1daefc7 100644
--- a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java
+++ b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java
@@ -37,6 +37,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import java.util.stream.Stream;
 import org.apache.commons.io.IOUtils;
 import org.junit.runner.Description;
@@ -199,7 +200,21 @@ public class TeaVMTestRunner extends Runner {
         }
 
         if (success && outputDir != null) {
-            runInTeaVM(child, notifier, expectedExceptions);
+            Description description = describeChild(child);
+            List<TeaVMTestConfiguration> configurations = getConfigurations();
+            int[] configurationIndex = new int[] { 0 };
+            List<Consumer<Boolean>> onSuccess = new ArrayList<>();
+
+            onSuccess.add(runSuccess -> {
+                if (runSuccess && configurationIndex[0] < configurations.size()) {
+                    runInTeaVM(child, notifier, expectedExceptions, configurations.get(configurationIndex[0]++),
+                            onSuccess.get(0));
+                } else {
+                    notifier.fireTestFinished(description);
+                    latch.countDown();
+                }
+            });
+            onSuccess.get(0).accept(true);
         } else {
             if (!run) {
                 notifier.fireTestIgnored(describeChild(child));
@@ -247,41 +262,41 @@ public class TeaVMTestRunner extends Runner {
         return true;
     }
 
-    private boolean runInTeaVM(Method child, RunNotifier notifier, Set<Class<?>> expectedExceptions) {
+    private boolean runInTeaVM(Method child, RunNotifier notifier, Set<Class<?>> expectedExceptions,
+            TeaVMTestConfiguration configuration, Consumer<Boolean> onComplete) {
         Description description = describeChild(child);
 
         CompileResult compileResult;
         try {
-            compileResult = compileTest(child);
-        } catch (IOException e) {
+            compileResult = compileTest(child, configuration);
+        } catch (Exception e) {
             notifier.fireTestFailure(new Failure(description, e));
+            onComplete.accept(false);
             return false;
         }
 
         if (!compileResult.success) {
             notifier.fireTestFailure(new Failure(description,
                     new AssertionError(compileResult.errorMessage)));
-            notifier.fireTestFinished(description);
-            latch.countDown();
+            onComplete.accept(false);
             return false;
         }
 
         if (runStrategy == null) {
-            notifier.fireTestFinished(description);
-            latch.countDown();
+            onComplete.accept(true);
             return true;
         }
 
         TestRunCallback callback = new TestRunCallback() {
             @Override
             public void complete() {
-                notifier.fireTestFinished(description);
-                latch.countDown();
+                onComplete.accept(true);
             }
 
             @Override
             public void error(Throwable e) {
                 notifier.fireTestFailure(new Failure(description, e));
+                onComplete.accept(false);
             }
         };
 
@@ -325,14 +340,22 @@ public class TeaVMTestRunner extends Runner {
         }
     }
 
-    private CompileResult compileTest(Method method) throws IOException {
+    private CompileResult compileTest(Method method, TeaVMTestConfiguration configuration) throws IOException {
         CompileResult result = new CompileResult();
 
         File path = outputDir;
         path = new File(path, method.getDeclaringClass().getName().replace('.', '/'));
         path = new File(path, method.getName());
         path.mkdirs();
-        File outputFile = new File(path, "test.js");
+
+        StringBuilder simpleName = new StringBuilder();
+        simpleName.append("test");
+        String suffix = configuration.getSuffix();
+        if (!suffix.isEmpty()) {
+            simpleName.append('-').append(suffix);
+        }
+        simpleName.append(".js");
+        File outputFile = new File(path, simpleName.toString());
         result.file = outputFile;
 
         resourceToFile("org/teavm/backend/javascript/runtime.js", new File(path, "runtime.js"));
@@ -345,12 +368,14 @@ public class TeaVMTestRunner extends Runner {
         Class<?> runnerType = testAdapter.getRunner(methodHolder);
 
         JavaScriptTarget jsTarget = new JavaScriptTarget();
-        jsTarget.setMinifying(false);
+        configuration.apply(jsTarget);
+
         TeaVM vm = new TeaVMBuilder(jsTarget)
                 .setClassLoader(classLoader)
                 .setClassSource(classSource)
                 .build();
         vm.setIncremental(false);
+        configuration.apply(vm);
         vm.installPlugins();
 
         new TestExceptionPlugin().install(vm);
@@ -373,6 +398,18 @@ public class TeaVMTestRunner extends Runner {
         return result;
     }
 
+    private List<TeaVMTestConfiguration> getConfigurations() {
+        List<TeaVMTestConfiguration> configurations = new ArrayList<>();
+        configurations.add(TeaVMTestConfiguration.DEFAULT);
+        if (Boolean.parseBoolean(System.getProperty("teavm.junit.minified", "false"))) {
+            configurations.add(TeaVMTestConfiguration.MINIFIED);
+        }
+        if (Boolean.parseBoolean(System.getProperty("teavm.junit.optimized", "false"))) {
+            configurations.add(TeaVMTestConfiguration.OPTIMIZED);
+        }
+        return configurations;
+    }
+
     private void applyProperties(Class<?> cls, Properties result) {
         if (cls.getSuperclass() != null) {
             applyProperties(cls.getSuperclass(), result);