如果局部变量不能被测试,那么可以通过其他方式检查变量值

时间:2017-12-01 12:33:06

标签: java unit-testing junit java-bytecode-asm bcel

这是一个很长的问题,需要知道某些东西是如何与传统方法相媲美的。

我遇到了一个非常有趣的应用程序codeacademy,它实际上是在main方法中测试局部变量。 这是该页面的屏幕截图,让我思考如何实现这一点。 enter image description here 在stackoverflow中发现了一些类似的问题。

Is it possible to obtain variables in main method from junit test?

How to use BCEL or ASM to get the value of a local declared variable in JAVA?

我不满足于知道它无法完成,我想知道的是,是否有一种方法,比如java编译器api或其他一些方法,可以让我知道这样的应用程序是如何制作的可能。

2 个答案:

答案 0 :(得分:2)

在实现验证中测试局部变量(如单元测试或QA自动测试)通常是不好的做法。

局部变量取决于特定的实现,特定的实现应隐藏在合理抽象的API背后,以允许开发人员在将来替换实现 - 如果他们有更好的想法 - 而不影响消费者的结果(只要,因为API非常好,所以不需要任何更改。)

对于一些非常复杂的实现/算法,开发人员确实可能有兴趣验证复杂算法的特定中间/内部结果,以使实现本身的开发更容易。在这一点上,创建内部内部API提供合理抽象的中间结果是有意义的,即使它们与特定算法硬绑定,并在单元测试中测试内部API。但是在替换算法的情况下,您必须接受内部API的更改以及所有内部单元测试。应该仍然有合理的高级抽象API,它不受内部变化的影响。

需要对局部变量的级别进行测试,这应该表明代码库存在一些更深层次的问题。

您对Java教程的特定用例与真正的Java代码开发完全无关,因为该讲座的目的完全不同。

正如简单的myNumber = 21 + 21;测试所示,讲座的验证纯粹基于比较文本,可能使用学生输入的源代码的一些正则表达式。甚至不检查生成的字节码,因为它与myNumber = 42;相同。

如果您正在使用某种讲座系统,使用某种自定义虚拟机和调试界面可能会有效,但如果是简单的讲座,即使是文本比较解决方案也可能就足够了。

通常当学生足够先进以解决某些任务时,您可以开始使用来自/到stdin / stdout的输入/输出来创建自动化测试,以通过一组已知的输入/输出测试来验证学生解决方案,就像某些网站一样https://www.hackerrank.com/做或各种节目竞赛。此时您不需要访问任何东西,也不需要本地变量,也不需要API单元测试,您只需将stdin重定向到需要输入的Feed解决方案,并捕获stdout以将其与设计输出进行比较。

但讲座验证与单元测试完全无关。

对预期结果进行过于严格的测试可能会在讲座过程中产生反作用!

想象一下,你要求学生编写代码,输出从1到N的平方和,你只会接受:

    int sum = 0;
    for (int i = 1; i <= N; ++i) {
        sum += i * i;
    }

(在字节码级别验证,以变量名称和++后缀/前缀无关紧要的方式)

现在有些学生会尝试提交:

    int sum = 0, square = 0, sq_delta = -1;
    for (int i = 1; i <= N; ++i) {
        sum += (square += (sq_delta += 2));
    }

它会失败......(即使他的解决方案在1985年左右绝对优于实际乘法的变体)......悲伤的故事。 :)

答案 1 :(得分:0)

可能我们过度思考这个问题。

当我收到您的问题时,您想知道这里使用的在线工具如何知道某些main()方法中变量的内容

事情是:这不一定是Java功能。

请注意:它是他们的网络应用程序。他们可以在那里做任何他们实施的事情。换句话说:当然,您可以使用Java编译器生成任何 Java代码片段的AST(抽象语法树)表示。当然,AST包含相应源代码中存在的所有信息。