Node.js 可能有比我';我在做高级测试?

Node.js 可能有比我';我在做高级测试?,node.js,testing,high-level,Node.js,Testing,High Level,嗯,我对测试还很陌生,但我想将编程提升到下一个层次并开始测试,没有单元测试,只有高级测试。例如:插入一个作业,并通过检查其输入和结果来检查它是否有效。或者另一个例子:插入一个作业,然后worker X启动了它:现在我将检查作业和worker的属性,以了解它们是否处于有效状态 但是这是非常非常复杂的,所以我一直在考虑在每个测试中做一个环境和一个实例,每个环境创建一个服务器实例,并分配一个空数据库来使用 例如,启动作业高级案例: var environment = new GenericEnviro

嗯,我对测试还很陌生,但我想将编程提升到下一个层次并开始测试,没有单元测试,只有高级测试。例如:插入一个作业,并通过检查其输入和结果来检查它是否有效。或者另一个例子:插入一个作业,然后worker X启动了它:现在我将检查作业和worker的属性,以了解它们是否处于有效状态

但是这是非常非常复杂的,所以我一直在考虑在每个测试中做一个环境和一个实例,每个环境创建一个服务器实例,并分配一个空数据库来使用

例如,启动作业高级案例:

var environment = new GenericEnvironment(test); // test will be used to throw errors within the environment when something goes wrong.
environment.insertWorker({name: 'bla bla', number 99});
environment.insertARandomProduct();
environment.insertJob({productId: product._id})
environment.startJob({workerId: worker._id})
var environmentValidator = new environmentValidators.StartJobEV()
var job = environment.getLastInsertedJob(environment, test);
environment.validate(job);
// node.js (Javascript on server)
这个例子非常简单,因为在现实世界中它使用异步回调

environmentValidator使用环境中的数据检查作业是否处于有效状态。例如,还可以让正在作业中工作的工作人员检查其状态是否繁忙

但我不认为这是非常好的,因为我在测试创建的开始,我问您是否有可能改进这些高级测试的方法

另外,我想知道是否有任何现有的框架用于此类测试

谢谢

真实代码,但仅用于检查插入作业后的状态:

    var serverManager = new ServerManager(test.getPathForDatabase());
    require('production/tests/tottys/_environments/DefaultEnvironment');
    var environment = new production.tests.tottys._environments.DefaultEnvironment(test, serverManager);

    var dummyData = {}

    test.addStep('initEnvironment', function(nextStep){
        environment.init();
        environment.addListener('afterInitialized', function(){
            nextStep();
        }, this);
    });

    test.addStep('insertWorker', function(nextStep){
        dummyData.worker = environment.insertRandomWorker(function(data){
            nextStep();
        });
    });

    test.addStep('insertProduct', function(nextStep){
        dummyData.product = environment.insertRandomProduct(function(data){
            nextStep();
        });
    });

    test.addStep('insertJob', function(nextStep){
        var worker = environment.getLastInsertedWorker();
        var product = environment.getLastInsertedProduct();
        dummyData.job = environment.insertRandomJob(worker, product, function(data){
            nextStep();
        });
    });

    test.addStep('updateWorker', function(nextStep){
        environment.updateWorker({workerId: environment.getLastInsertedWorker()._id}, function(data){
            nextStep();
        });
    });

    test.addStep('validateInsertedJob', function(nextStep, test){
        require('production/tests/tottys/_environmentValidators/AfterJobInserted');
        var EV = new production.tests.tottys._environmentValidators.AfterJobInserted(environment, test);
        var job = environment.getLastInsertedJob();
        EV.addListener('validationEnded', function(e){
            nextStep();
        });
        EV.validate(job, dummyData);
    });
    test.start();
和验证文件:

qx.Class.define("production.tests.tottys._environmentValidators.AfterJobInserted", {
     extend: qx.core.Object


    ,properties: {
    }


    ,events: {
        validationEnded: 'qx.event.type.Data'
    }


    ,construct: function(environment, test){
        this.__environment = environment;
        this.__test = test;
    }


    ,members: {
        validate: function(job, dummyData){
            this.__job = job;
            this.__dummyData = dummyData;
            this.__environment.getWorkerForJob(job, this.__afterWorkerReturned, this);
            this.__environment.getProductForJob(job, this.__afterProductReturned, this);
        }



        ,__afterWorkerReturned: function(worker){
            this.__worker = worker;
            this.__tryStartValidation();
        }



        ,__afterProductReturned: function(product){
            this.__product = product;
            this.__tryStartValidation();
        }



        ,__tryStartValidation: function(){
            if(this.__preConditionsAreValid()){
                this.__startValidation();
            }
        }



        ,__preConditionsAreValid: function(){
            if(this.__worker && this.__product){
               return true;
            }
            return false;
        }



        ,__startValidation: function(){
            var test = this.__test;
            var dummyData = this.__dummyData;
            var job = this.__job;
            var worker = this.__worker;
            var product = this.__product;

            test.add("Expect job not to be done.", function(expect){
                expect(job.done).toBe(false);
            })

            test.add("Expect job's requested quantity to be the same as requested.", function(expect){
                expect(job.qtdRequested).toBe(dummyData.job.qtdRequested);
            })

            test.add("Expect job's missing quantity be the same as requested.", function(expect){
                expect(job.qtdMissing).toBe(dummyData.job.qtdRequested);
            })

            test.add("Expect to be requested by the same request type.", function(expect){
                expect(job.requestedByType).toBe('manager')
            })

            test.add("Expect job not to be done.", function(expect){
                expect(job.done).toBe(false);
            })

            test.add("Expect job's done quantity to be '0' (Number)", function(expect){
                expect(job.qtdDone).toBe(0);
            })

            test.add("Expect job to not have any time frames.", function(expect){
                expect(job.timeFrames && job.timeFrames.length > 0).notToBe(true);
            })

            test.add("Expect job's date end to not exist.", function(expect){
                expect(job.dateJobEnd).notToExist();
            })

            test.add("Expect job's date request to exist.", function(expect){
                expect(job.dateRequested).toExist();
            })

            test.add("Expect job's state to be 'todo'.", function(expect){
                expect(job.state).toBe('todo');
            })

            test.add("Expect job's order to be '0' (Number).", function(expect){
                expect(job.order).toBe(0);
            })

            test.add("Expect job's worker's name to be the same as the requested one.", function(expect){
                expect(job.forWorker.name).toBe(dummyData.worker.name);
            })

            test.add("Expect job's worker's number to be the same as the requested one.", function(expect){
                expect(job.forWorker.number).toBe(dummyData.worker.number);
            })

            test.add("Expect job's worker's _id to be the same as the generated one.", function(expect){
                console.log(worker);
                expect(job.forWorker._id.toString()).toBe(worker._id.toString());
            })

            test.add("Expect job's product's code to be the same as the requested one.", function(expect){
                expect(job.product.code).toBe(dummyData.product.code);
            })

            test.add("Expect job's product's description to be the same as the requested one.", function(expect){
                expect(job.product.description).toBe(dummyData.product.description);
            })

            test.add("Expect job's product's _id to be the same as the requested one.", function(expect){
                expect(job.product._id.toString()).toBe(product._id.toString());
            })
            this.fireDataEvent('validationEnded', {err: false})
        }
    }

});

如果您从测试开始,那么进行“高级”或“集成测试”(IT)总是很诱人的。它比“单纯的”单元测试感觉更自然、更“容易”和更强大。您已经运行了整个系统,为什么不在此基础上进行测试

但和软件开发一样,这意味着你有更多的依赖性。如果要运行这些测试,数据库必须处于特定状态。服务器必须运行。你需要一个浏览器。网络应该起作用。对于它,整个系统必须处于一个精确定义的状态,您需要工具使系统处于这种状态-您必须在每次单独测试之前这样做

问题是:每个依赖项都是错误的来源。如果依赖项的数量达到某一点,其中一个依赖项将始终被破坏,并且您的测试将失败。不是因为代码被破坏了,而是因为创建初始状态变得太复杂了

这就是为什么您应该真正从单元测试开始。找到系统中没有依赖项的最小组件并进行测试

这种方法的优点:

  • 它降低了复杂性。与此相反,测试通常或总是会成功
  • 测试用例将更小。你不需要花一个小时就能弄清楚你需要什么样的初始状态和最终状态
  • 设置将更加简单(通常,您不会有任何或1-2行设置)
  • 依赖项中的更改不会破坏其他测试。有了它,一个微小的变化就可以打破所有其他的测试
  • 如果您知道所有单个组件都正常工作,那么代码其余部分中的bug将自动消失
  • 修复bug会容易得多。如果您只测试了10行代码,那么任何bug都必须出现在这10行代码中。如果你运行一个IT,这个bug可能在任何地方

  • 结论:从一些单元测试开始。当您对所有内容都进行单元测试时,为整个系统编写单元测试将变得更加简单。。。如果您需要的话。

    什么站台?什么语言?node.js javascript。如果你考虑一下这个框架,我只想知道从他们那里得到一些想法:D(无论如何,这不是特定于语言的…)看看这个:,和。你认为为这种应用做单元作业更好吗?是的,因为我在你的代码中没有看到任何真正的测试。您只运行一些函数,但从不断言结果。错误处理没有在任何地方进行测试。您可以调用验证函数,但每个函数只调用一次。用不同的输入再次测试它们怎么样?