leetcode刷题神器 - 本地一行命令执行多个测试用例

1,155 阅读2分钟

leetcode刷题时有时只能通过部分测试用例,来回提交代码比较费时费力,这里提供了让代码在本地跑多个测试用例并打印每个测试用例执行结果的调试工具。

  • 使用姿势: 一行命令即可执行多个测试用例
node run.js "1.array-reverse"
# Problem: 1.array-reverse
#   run-time: 0.028ms
# ✓ 1. example success: { argus: [ [ 3, 2, 1 ] ], result: [ 3, 2, 1 ] }
#   run-time: 0.017ms
# ✓ 2. example success: { argus: [ [ 7, 8, 9 ] ], result: [ 7, 8, 9 ] }
#   run-time: 0.004ms
# ✗ 3. example error: { argus: [ [ 6, 5, 4 ] ], result: [ 5, 4, 6 ] } expect: [ 5, 4, 6 ] , but get:  [ 6, 5, 4 ]

一、说明

  • 语言:Javascript
  • 执行环境:nodejs(浏览器环境如果有需要请在评论中备注,有需要后续会出)

二、使用使用介绍

1. 目录结构

src
├─run.js
├─problems
|    ├─1.array-reverse
|    |    ├─README.md
|    |    ├─code.js
|    |    └examples.js
|    ├─2.other-problem

2. 测试用例examples.js

const examples = [
    {
        argus: [[1,2,3]],
        result: [3,2,1]
    },
    {
        argus: [[9,8,7]],
        result: [7,8,9]
    },
    {
        argus: [[4,5,6]],
        result: [5,4,6]
    }
];

module.exports = examples;

3. 代码code.js

/**
 * @param {Array} arr
 * @return {Array}
 */
var fun = function(arr) {
    return arr.reverse();
};

module.exports = fun;

4. 代码执行器及结果判定run.js

const name = process.argv[2];
/**
 * 根据序号获取题目代码和测试用例
 */
function getProblemConfig(name) {
    const code = require(`./problems/${name}/code.js`);
    const examples = require(`./problems/${name}/examples.js`);
    return {
        core: code,
        examples
    };
}
/**
 * 执行器
 */
function run(key) {
    const problem = getProblemConfig(key);
    if (!problem) {
        console.log(`✗ Error: Problem ${key} not found!`);
        return;
    }
    const code = problem.core;
    console.log('\n');
    console.log(`Problem: ${problem.title}`);
    problem.examples.forEach((example, index) => {
        let result = undefined;
        try{
            result = code.apply(null, example.argus);
        } catch(err) {
            console.log(`✗`, index + 1 + '. example error:', example, 
            'run code error:', err);
        }
        if (resultIsOk(example.result, result)) {
            console.log(`✓`, index + 1 + '. example success:', example);
        } else {
            console.log(`✗`, index + 1 + '. example error:', example, 
            'expect:', example.result,
            ', but get: ', result);
        }
    });
    console.log('\n');
}

function typeOf(param) {
    return Object.prototype.toString.call(param).slice(8, -1).toLowerCase();
}
/**
 * 判断执行结果和预期结果是否一致
 */
function resultIsOk(expect, result) {
    let isOk = true;
    const type = typeOf(expect);
    if (type === 'function') {
        return expect(result);
    }  else if (type !== typeOf(result)) {
        return false;
    } else if (type === 'array') {
        if (expect.length !== result.length) {
            return false;
        }
        expect.forEach((e, i) => isOk = (isOk && resultIsOk(e, result[i]))); 
        return isOk;
    } else {
        return expect === result;
    }
}


run(name);

5. 执行命令

node run.js "1.array-reverse"
# Problem: 1.array-reverse
# ✓ 1. example success: { argus: [ [ 3, 2, 1 ] ], result: [ 3, 2, 1 ] }
# ✓ 2. example success: { argus: [ [ 7, 8, 9 ] ], result: [ 7, 8, 9 ] }
# ✗ 3. example error: { argus: [ [ 6, 5, 4 ] ], result: [ 5, 4, 6 ] } expect: [ 5, 4, 6 ] , but get:  [ 6, 5, 4 ]

6. 使用vscode断点调试

使用vscode断点调试代码,启动方式可以选择通过命令行启动,这样就可以给程序传入自定义的参数。

  • 左侧点击调试 Javascript Debug Terminal

  • 断点调试代码,可查看变量、调用栈等

  • 执行结果

三、待优化点

  • js输出的执行时间不太准,尤其在数据量比较小的时候
  • 输出消耗内存