【问题标题】:Calling a java method with array of testcases使用测试用例数组调用 java 方法
【发布时间】:2014-05-24 22:49:34
【问题描述】:

首先,我知道标题有点模棱两可。其实我不知道怎么写更好!

其次,我将描述问题。

情况:

我正在在线法官 (OJ) 上练习,所以如果输出错误,OJ 会向我显示导致我的代码失败的测试用例。通常,我可以复制我的代码并将其粘贴到 Eclipse 中,然后使用该测试用例调用我的 function 并调试我的代码。

但是当测试用例是多次调用我的函数时的问题(就像测试优先级队列的增强版本),让我们假设在代码失败之前有 n 次调用。所以要调试代码,我将不得不调用 function 说 n 次!这不合逻辑!

OJ 将调用的函数:

public void enqueue (int value)
{
    // implementation
}
public int dequeue ()
{
    // implementation
}

测试用例使代码失败:

Last executed input: enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16),... dequeue(),...

行动:

我需要一种方法来调用带有一组测试用例的函数,以便能够调试代码。

通过某种方式直接从字符串中调用带有参数的函数。类似invoke("enqueue(5, 3)");

【问题讨论】:

    标签: java unit-testing testing


    【解决方案1】:

    经过一番调查,我找到了一种方法来执行我需要的操作,方法是使用Java Reflection 也是一个有用的线程What is reflection and why is it useful?

    我设法开发了一个工具,步骤如下:

    1. 将测试用例复制到字符串中
    2. 在每个函数调用中拆分字符串
    3. 从每个调用中删除函数名,并按顺序存储在String数组中。
    4. 拆分参数
    5. 现在我有 2 个整数数组用于 param1 和 param2,还有一个 String 数组用于调用

    我使用反射是为了能够在 for 循环内从一串调用中调用方法。

    那么我们就有了这个

    public class Test
    {
        public static void main(String[] args)
        {
            String testCase = "enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16), dequeue()";
            // Prepare parameters and invocations
            int[] param1; // assuming it is ready
            int[] param2; // assuming it is ready
            String[] calls; // assuming it is ready
    
            try
            {
                Class calledClass = Class.forName("OJ.Prob3");
                Method calledMethod1 = calledClass.getDeclaredMethod("enqueue", String.class, int.class);
                Method calledMethod2 = calledClass.getDeclaredMethod("dequeue", null);
                for (int i = 0 ; i < calls.length ; i++)
                {
                    if (calls[i].equalsIgnoreCase("enqueue"))
                        calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]);
                    else if (calls[i].equalsIgnoreCase("dequeue"))
                        calledMethod2.invoke(calledClass.newInstance())
                }
            } catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            } catch (NoSuchMethodException e)
            {
                e.printStackTrace();
            } catch (SecurityException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
        }
    }
    

    我已经测试过这个解决方案,它运行起来非常流畅,但是如果有人有更好的解决方案,我们会非常欢迎您。

    我会敲定代码,把它变成一个工具,我会尽快发布,为了让大家更轻松地调试在线评委测试用例。

    更新:
    您可以对静态方法执行相同的操作,只需将 .newInstance()calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]); 删除为 calledMethod1.invoke(calledClass, param[i], param2[i]); 之类的东西

    【讨论】:

    • 你为什么不直接打电话给enqueue(5, 3); 和其他人呢?这增加了什么?您仍然可以输入它,但现在它还需要调用解析和反射。
    • @JeroenVannevel 你能告诉我怎么做吗?因为你是对的,所以我试着按照你说的方式去做,但我想不通......
    • 哦,好吧,我明白你的意思了。您的代码非常令人困惑,因为它没有显示任何断言语句(甚至没有任何类型的视觉检查输出),并且testCase 字符串使它看起来像是程序的一部分。当我说您解析 testCase 而不是手动添加值时,我是否正确?
    • @JeroenVannevel 是的,我解析了它。主要问题是我从 在线法官 收到了testCase 字符串,例如TopCoder,而我想要在我的本地机器上检查相同的情况以便能够对其进行调试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    相关资源
    最近更新 更多