Java 如果无法测试局部变量,那么可以通过哪些其他方式检查变量值

Java 如果无法测试局部变量,那么可以通过哪些其他方式检查变量值,java,unit-testing,junit,java-bytecode-asm,bcel,Java,Unit Testing,Junit,Java Bytecode Asm,Bcel,这将是一个很长的问题,因为人们渴望知道某些东西是如何与传统方法相违背的 我遇到了一个非常有趣的应用程序,它实际上是在一个主方法中测试局部变量。 这是该页面的截图,它让我思考这是如何可能的。 在stackoverflow中发现了一些类似的问题 我不满足于知道这是不可能的,我想知道的是,有没有一种方法,像java编译器api或其他什么方法,可以让我知道这样的应用程序是如何实现的 也许我们考虑得太多了 当我收到你的问题时,你想知道这里使用的在线工具如何知道一些main()方法中变量的内容 问题是:

这将是一个很长的问题,因为人们渴望知道某些东西是如何与传统方法相违背的

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


我不满足于知道这是不可能的,我想知道的是,有没有一种方法,像java编译器api或其他什么方法,可以让我知道这样的应用程序是如何实现的

也许我们考虑得太多了

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

问题是:这不一定是Java特性


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

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

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

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

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


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

如简单的
myNumber=21+21所示测试,课程的验证完全基于文本比较,可能使用一些正则表达式对学生输入的源代码进行验证。甚至不检查结果字节码,因为该字节码与
myNumber=42相同

如果您在某个讲课系统上工作,使用某种自定义虚拟机和调试界面可能会起作用,但对于简单的讲课,即使是文本比较解决方案也可能足够了

通常,当学生足够高级,可以解决某些任务时,您可以开始使用输入/输出自/到标准输入/标准输出来创建自动测试,以使用一组已知的输入/输出测试来验证学生的解决方案,如一些站点(如do)或各种编程竞赛。在这一点上,您不需要访问任何东西,也不需要访问局部变量,也不需要API单元测试,您只需重定向stdin以向解决方案提供所需的输入,并捕获stdout以将其与设计的输出进行比较


但课堂验证与单元测试完全无关

对预期结果进行过多的严格测试甚至可能会在授课过程中产生反作用

假设您让学生编写代码,输出从1到N的平方和,您只接受:

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

对于(int i=1;i局部变量的值在测试中无关紧要,因为一旦方法退出,它们就不存在了。您应该只关心在方法生命周期之外可以观察到的事情,例如返回值、异常、成员变量、依赖项上的方法调用。因此,您可能会在您正在调试;这就是调试器的用途。请避免使用屏幕截图。您可以将代码作为文本放入问题中;您也可以简单地将说明作为代码引用。图像不适用于屏幕阅读器-并且您的问题中没有任何内容需要使用图像!它可能使用调试界面。Wh在Eclipse中调试时,您也会看到局部变量。这并不意味着我会支持对方法内部进行单元测试的想法-一点也不!那么在codeacademy网站上会发生什么,如果您执行
myNumber=21+21;
,它会接受吗?那么
myNumber=(myNumber=21)呢然后,它解析文本而不是编译的代码,因为
myNumber=21+21
编译成与
myNumber=42
完全相同的字节码。对于这段微不足道的代码,甚至可以使用传统的Java编译器(
javac
ecj
)进行编译启用调试信息并遵循代码流预测变量的最终值。它不包含任何静态代码分析无法预测的内容。当然,这也是为什么此代码不值得进行单元测试的原因。单元测试开始,可预测性结束…我不完全同意。单元测试有几个功能:A)在执行TDD时,它们从您的需求的可运行规范开始B)它们应该帮助查找错误/回归C)大多数代码应该是可预测的。。。或者你写的代码你不知道它会做什么?从这个意义上说:这是非常有意义的
    int sum = 0, square = 0, sq_delta = -1;
    for (int i = 1; i <= N; ++i) {
        sum += (square += (sq_delta += 2));
    }