在AWS Lambda上运行JUnit Test:java.lang.Exception:没有可运行的方法

时间:2019-08-06 18:42:02

标签: java amazon-web-services junit aws-lambda

我已经编写了代码来下载测试用例,并在Java 8环境中的AWS Lambda中运行它。

private static Class<?> loadClass(String className) throws ClassNotFoundException, MalformedURLException {
    // Load compiled class.
    File root = new File("...");
    URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{root.toURI().toURL()});
    return Class.forName(className, true, classLoader);
}

public static String run(RunRequest req) throws IOException {
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream ps = new PrintStream(baos, true, "UTF-8");

    try {
        // Download test case
        CloudStorage.downloadChallenge(req.getChallengeId());
        // Get test case class
        String className = Database.getChallengeTestClass(req.getChallengeId());
        // Load test case
        Class<?> test = loadClass(className);

        System.out.println("Test: " + test.getName());

        // Run test case
        JUnitCore junit = new JUnitCore();
        junit.addListener(new TextListener(ps));

        junit.run(test);
    } catch (Exception e) {
        e.printStackTrace(ps);
    } finally {
        return new String(baos.toByteArray(), StandardCharsets.UTF_8);
    }
}

当我在机器上本地测试此代码时,它可以完美执行,并且从JUnit获得以下输出:

Time: 0.002

OK (1 test)

但是,当我在Lambda上运行相同的代码时,会产生以下错误:

Time: 0.014
There was 1 failure:
1) initializationError(com.test.util.UnitTest)
java.lang.Exception: No runnable methods
    at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:191)
    at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:128)
    at org.junit.runners.ParentRunner.validate(ParentRunner.java:416)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
    ...

FAILURES!!!
Tests run: 1,  Failures: 1

有什么想法会发生这种情况吗?我正在运行junit 4.12

另外,正在运行的测试用例如下:

package com.test.util;

import junit.framework.TestCase;

public class UnitTest {
  public UnitTest() {}

  @org.junit.Test
  public void test() {
    System.out.println("Runnning test...");

    TestCase.assertTrue(Runner.userCode.toString().equals("Hello World!"));
  }
}

该类已正确导入,因为它显示com.test.util.UnitTest

1 个答案:

答案 0 :(得分:0)

我发现了问题。

正在发生的事情是,我使用静态变量Runner引用了另一个类userCode,但正在使用新的ClassLoader加载此类。对于此ClassLoader,类Runner不存在,因此Java不会加载引用此静态变量的方法。它与Lambda无关。我从this thread中了解了这一点,它解释了Java ClassLoader的某些行为。

我唯一的问题是为什么它在我的计算机上本地工作?我不能在这里解释不一致之处。

谢谢!