【问题标题】:Testing/validating/evaluating the outcome of every path in a function?测试/验证/评估函数中每条路径的结果?
【发布时间】:2013-08-26 11:28:21
【问题描述】:

免责声明 - 我已尝试通过 google/stackoverflow 找到答案,但我不知道如何定义问题(我不知道正确的术语)

我有很多小的 AI sn-ps 如下所示。每种敌人类型都有一个._ai sn-p(如下所示),其中一个函数next() 在主游戏循环中由有限状态机调用(仅供参考:next 函数并非每次都被调用更新迭代,仅当敌人从队列中移出时)。

问题:我如何测试每个案例(考虑到一些敌人的 AI sn-ps 可能更复杂,可能会出现千分之一的案例)并确保代码有效?

在下面的示例中,如果我在 count++ 下添加了行 blabla/1,则错误可能很长时间都不会出现,因为 Javascript 解释器在到达特定路径之前不会捕获错误。在编译语言中,添加诸如blabla/1 之类的垃圾会在编译时被捕获。

// AI Snippet
this._ai = (function(commands){
    var count = 0;

    return {
        next: function(onDone, goodies, baddies) {

            // If the internal counter reaches
            // 2, launch a super attack and 
            // reset the count
            if(count >= 2) {
                commands.super(onDone);
                count = 0;
            }
            else {
                // If not performing the super attack
                // there is a 50% chance of calling
                // the `attack` command
                if(chance(50)) {
                    var target = goodies[0];
                    commands.attack(onDone, target);
                } 
                // Or a 50% chance of calling the 
                // `charge` command
                else {
                    commands.charge(onDone);
                    count++;
                }
            }
        }
    };
})(this._commands); 

我可以装配随机生成器以从0-n 返回一个值表,并对每个数字运行next 1000 次。我只是不觉得那会具体告诉我每条路径都没有错误。

【问题讨论】:

  • "确保代码有效" -- 什么定义了有效性?
  • Valid 可能是错误的措辞,我的意思是没有错误。从某种意义上说,所有路径都不会抛出错误
  • 只能自动测试纯函数。由于连续两次调用相同的函数会返回不同的结果,因此无法测试每个结果。
  • 当然有选择。重构代码并非不可能
  • 这是一个无法确定的问题,如果你愿意,我可以证明这一点。

标签: javascript unit-testing


【解决方案1】:

正如您所说,单元测试必须测试每条路径,这样您才能确保一切正常。

但您应该能够在测试中调用该方法之前确定该方法将遵循的路径,这样您就可以知道该方法的行为是否是预期的行为,以及是否有任何错误。

因此,例如,如果每 1000 次执行中只有一次会遵循一条路径,则您不需要测试所有 0、1、2 ... 999 个案例。您只有一种表现明显的结果组合。

例如,在显示的 sn-p 中,您有以下情况:

  • 计数器已达到 2
  • 计数器未达到 2,机会返回 true
  • 计数器未达到 2,机会返回 false

实现这一点的一种方法是通过模拟它们来控制计数器和机会方法。

如果您想知道当计数器达到 2 并调用 next 方法时会发生什么,只需传递一个带有 2 的计数器并调用 next。您不需要通过真正传递所有代码来达到计数器上的 2。

至于随机化器,在随机化器返回您要测试的值之前,您无需尝试。将其设为模拟并将其配置为根据每个案例的需要运行。

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多