异步服务(ftp)的实习测试不会对错误进行测试失败

时间:2015-03-03 05:42:34

标签: node.js asynchronous tdd intern

我已经编写了一个实习测试,其工作是建立FTP连接并通过连接执行操作。如果任何步骤失败,则测试应该失败。我有两个版本,一个尝试手动拒绝或解析async dfd,另一个尝试使用callback()和rejectOnError()函数自动拒绝或解析dfd。

我已阅读https://github.com/jason0x43/intern-wiki/blob/master/Writing-Tests-with-Intern.md,但发现它太短暂,无法真正看出我做错了什么。

这些脚本故意尝试i_do_not_exist'为了强迫错误。

脚本1 - 手动拒绝或解析dfd:

/*jshint dojo:true */
/*global console:true */
'use strict';
define([
    'intern!tdd',
    'intern/dojo/node!jsftp',
    'intern/chai!assert'
], function (test, JSFtp, assert) {

    test.suite('FTP Test', function () {
        var promise,
            creds = {
                "host": "ftp.ed.ac.uk",
                "port": 21,
                "user": "anonymous",
                "pass": "tester@somewhere.com"
            };

        test.test('Check FTP availability', function () {
            var dfd = this.async(30000);

            console.log('Making FTP connection...');
            var ftp = new JSFtp(creds);

            ftp.auth(creds.user, creds.pass, function (err, res) {
                console.log('FTP auth result: err: ', err, ' res: ', res);
                console.log('typeof err: ' + typeof err);
                console.dir(err);
                if (err) {
                    dfd.reject(err.message);
                    return;
                }

                ftp.ls('i_do_not_exist', function(err, res) {
                    console.log('Ftp result: err: ', err, ' res: ', res);
                    if (err) {
                        console.error('Error in ls, failing FTP test.');
                        dfd.reject.bind(dfd);
                        return;
                    }

                    console.log('ls succeeded.');

                    // Got to do a raw quit when success or fail
                    ftp.raw.quit(function(err, data) {
                        console.log('Closed ftp: err: ', err, ' data: ', data);

                        if (err) {
                            console.log('Quit failed, test failed.');
                            dfd.reject.bind(dfd);
                        } else {
                            console.log('Quit OK, test succeeded.');
                            dfd.resolve('ftp ok');
                        }
                    });
                });
                return dfd;
            });
            return dfd;
        });
    });
});

脚本1的输出:

$ ../node_modules/.bin/intern-client config=intern suites=FTPTest reporters=console
Making FTP connection...
FAIL: main - FTP Test - Check FTP availability (30008ms)
Error: Timeout reached on main - FTP Test - Check FTP availability
    at Error (<anonymous>)
    at new ErrorCtor (/home/neek/src/WIN/monitoring/node_modules/intern/node_modules/dojo/errors/create.js:13:21)
    at null._onTimeout (/home/neek/src/WIN/monitoring/node_modules/intern/lib/Test.js:196:39)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
0/1 tests passed
0/1 tests passed

------------------------------------------+-----------+-----------+-----------+-----------+
File                                      |   % Stmts |% Branches |   % Funcs |   % Lines |
------------------------------------------+-----------+-----------+-----------+-----------+
   node_modules/intern/                   |     85.71 |        50 |       100 |     85.71 |
      chai.js                             |     85.71 |        50 |       100 |     85.71 |
   node_modules/intern/lib/               |     63.77 |     47.37 |     44.44 |     63.77 |
      Test.js                             |     63.77 |     47.37 |     44.44 |     63.77 |
   node_modules/intern/lib/interfaces/    |     76.19 |        50 |     55.56 |     76.19 |
      tdd.js                              |     76.19 |        50 |     55.56 |     76.19 |
   node_modules/intern/lib/reporters/     |     60.87 |        35 |     57.14 |     60.87 |
      console.js                          |     60.87 |        35 |     57.14 |     60.87 |
   node_modules/intern/node_modules/chai/ |     34.23 |      5.02 |     23.76 |     35.49 |
      chai.js                             |     34.23 |      5.02 |     23.76 |     35.49 |
   src/                                   |     32.26 |         0 |        50 |     32.26 |
      FTPTest.js                          |     32.26 |         0 |        50 |     32.26 |
------------------------------------------+-----------+-----------+-----------+-----------+
All files                                 |     37.91 |      8.25 |     28.69 |     39.12 |
------------------------------------------+-----------+-----------+-----------+-----------+

FTP auth result: err:  null  res:  { code: 230,
  text: '230-This service is managed by Information Services.  It holds information\n which may be useful to system managers and space is provided for\n individuals and groups upon request.  Upload facilities are also\n available.  Anyone can make use of this service. \n \n The files called ls-lR and index are a list of all the files that are\n available from this server.  ls-lR.Z is a compressed version of this\n file.\n \n Files available on the archive are to be found in the \'pub\' directory.\n \n Upload facilities for file sharing\n ----------------------------------\n \n The directory \'incoming\' is a place where files may be stored.  This\n directory is provided as a resource for communicating files between\n University of Edinburgh users and others; it is not a free Internet\n resource.  If you put files here then please send mail to the FTP server\n maintainer (ftpmaster@ed.ac.uk) explaining what should be done with\n them.  If notification is not received, the files will be removed.  This\n directory is not readable so once files are placed here you will not be\n able to see them.  You should also contact the person who you are\n passing the files to and provide them with the server name and names of\n all the files e.g.:\n \n \t\tftp://ftp.ed.ac.uk/incoming/myfile.txt\n \n To retrieve files, the exact filename and path should be used e.g.:\n \n \t\tftp://ftp.ed.ac.uk/incoming/myfile.txt\n \n The directory \'edupload\' may be used by anyone connected to the\n University network to upload files in the same manner as above. \n However, no mail notification needs to be sent to the FTP server\n maintainer and files will remain in the directory for one week.  Please\n do NOT upload files to both this and the incoming directory - choose one\n or the other. \n \n Anyone may download files from /incoming or /edupload if they know the\n name of the file that is stored there. \n \n How to upload a file to the server\n ----------------------------------\n         \n It is best to use a command line ftp program.  Windows, Mac and Linux\n systems all provide a command line ftp client.  Open a command or\n terminal window and then type:\n \n         ftp ftp.ed.ac.uk\n \n Login using the username \'anonymous\' and use your email address as password.\n \n Next change your current working directory to either the incoming\n directory or the edupload directory (be aware that edupload can only be\n accessed from the University network). \n \n         cd /incoming\n \n Next upload your file(s) using the put command:\n \n         put myfile.txt\n \n Your file will then be loaded on the ftp server.  You will not be able\n to get a file listing of it though as the directory is protected. \n \n \n FTP Server Maintainer (email: ftpmaster@ed.ac.uk)\n 24th September 2010\n \n230 Anonymous access granted, restrictions apply',
  isMark: false,
  isError: false }
typeof err: object
null
Ftp result: err:  { [Error: 450 i_do_not_exist: No such file or directory] code: 450 }  res:  undefined
Error in ls, failing FTP test.
<script hangs here...>

脚本2 - 从每个范围抛出(或不抛出)以允许rejectOnError()和callback()执行拒绝或解析。

/*jshint dojo:true */
/*global console:true */
'use strict';
define([
    'intern!tdd',
    'intern/dojo/node!jsftp',
    'intern/chai!assert'
], function (test, JSFtp, assert) {

    test.suite('FTP Test', function () {
        var promise,
            creds = {
                "host": "ftp.ed.ac.uk",
                "port": 21,
                "user": "anonymous",
                "pass": "tester@somewhere.com"
            };

        test.test('Check FTP availability', function () {
            var dfd = this.async(30000);

            console.log('Making FTP connection...');
            var ftp = new JSFtp(creds);

            ftp.auth(creds.user, creds.pass, dfd.rejectOnError(function (err, res) {
                console.log('FTP auth result: err: ', err, ' res: ', res);
                console.log('typeof err: ' + typeof err);
                console.dir(err);
                if (err) {
                    throw err;
                }

                ftp.ls('i_do_not_exist', dfd.rejectOnError(function(err, res) {
                    console.log('Ftp result: err: ', err, ' res: ', res);
                    if (err) {
                        console.error('Error in ls, failing FTP test.');
                        throw err;
                    }

                    console.log('ls succeeded.');

                    // Got to do a raw quit when success or fail
                    ftp.raw.quit(dfd.callback(function(err, data) {
                        console.log('Closed ftp: err: ', err, ' data: ', data);

                        if (err) {
                            console.log('Quit failed, test failed.');
                            throw 'Quit failed';
                        } else {
                            console.log('Quit OK, test succeeded.');
                        }
                    }));
                }));
                return dfd;
            }));
            return dfd;
        });
    });
});

脚本2输出:

$ ../node_modules/.bin/intern-client config=intern suites=FTPTest2 reporters=console
Making FTP connection...
FTP auth result: err:  null  res:  { code: 230,
  text: '230-This service is managed by Information Services.  It holds information\n which may be useful to system managers and space is provided for\n individuals and groups upon request.  Upload facilities are also\n available.  Anyone can make use of this service. \n \n The files called ls-lR and index are a list of all the files that are\n available from this server.  ls-lR.Z is a compressed version of this\n file.\n \n Files available on the archive are to be found in the \'pub\' directory.\n \n Upload facilities for file sharing\n ----------------------------------\n \n The directory \'incoming\' is a place where files may be stored.  This\n directory is provided as a resource for communicating files between\n University of Edinburgh users and others; it is not a free Internet\n resource.  If you put files here then please send mail to the FTP server\n maintainer (ftpmaster@ed.ac.uk) explaining what should be done with\n them.  If notification is not received, the files will be removed.  This\n directory is not readable so once files are placed here you will not be\n able to see them.  You should also contact the person who you are\n passing the files to and provide them with the server name and names of\n all the files e.g.:\n \n \t\tftp://ftp.ed.ac.uk/incoming/myfile.txt\n \n To retrieve files, the exact filename and path should be used e.g.:\n \n \t\tftp://ftp.ed.ac.uk/incoming/myfile.txt\n \n The directory \'edupload\' may be used by anyone connected to the\n University network to upload files in the same manner as above. \n However, no mail notification needs to be sent to the FTP server\n maintainer and files will remain in the directory for one week.  Please\n do NOT upload files to both this and the incoming directory - choose one\n or the other. \n \n Anyone may download files from /incoming or /edupload if they know the\n name of the file that is stored there. \n \n How to upload a file to the server\n ----------------------------------\n         \n It is best to use a command line ftp program.  Windows, Mac and Linux\n systems all provide a command line ftp client.  Open a command or\n terminal window and then type:\n \n         ftp ftp.ed.ac.uk\n \n Login using the username \'anonymous\' and use your email address as password.\n \n Next change your current working directory to either the incoming\n directory or the edupload directory (be aware that edupload can only be\n accessed from the University network). \n \n         cd /incoming\n \n Next upload your file(s) using the put command:\n \n         put myfile.txt\n \n Your file will then be loaded on the ftp server.  You will not be able\n to get a file listing of it though as the directory is protected. \n \n \n FTP Server Maintainer (email: ftpmaster@ed.ac.uk)\n 24th September 2010\n \n230 Anonymous access granted, restrictions apply',
  isMark: false,
  isError: false }
typeof err: object
null
Ftp result: err:  { [Error: 450 i_do_not_exist: No such file or directory] code: 450 }  res:  undefined
Error in ls, failing FTP test.
FAIL: main - FTP Test - Check FTP availability (12732ms)
Error: 450 i_do_not_exist: No such file or directory
    at Ftp.parse (/home/neek/src/WIN/monitoring/node_modules/jsftp/lib/jsftp.js:217:11)
    at Ftp.parseResponse (/home/neek/src/WIN/monitoring/node_modules/jsftp/lib/jsftp.js:136:8)
    at Stream.<anonymous> (/home/neek/src/WIN/monitoring/node_modules/jsftp/lib/jsftp.js:107:24)
    at Stream.EventEmitter.emit (events.js:95:17)
    at ResponseParser.reemit (/home/neek/src/WIN/monitoring/node_modules/jsftp/node_modules/event-stream/node_modules/duplexer/index.js:70:25)
    at ResponseParser.EventEmitter.emit (events.js:95:17)
    at ResponseParser.<anonymous> (_stream_readable.js:746:14)
    at ResponseParser.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
0/1 tests passed
0/1 tests passed

------------------------------------------+-----------+-----------+-----------+-----------+
File                                      |   % Stmts |% Branches |   % Funcs |   % Lines |
------------------------------------------+-----------+-----------+-----------+-----------+
   node_modules/intern/                   |     85.71 |        50 |       100 |     85.71 |
      chai.js                             |     85.71 |        50 |       100 |     85.71 |
   node_modules/intern/lib/               |     69.57 |     47.37 |        50 |     69.57 |
      Test.js                             |     69.57 |     47.37 |        50 |     69.57 |
   node_modules/intern/lib/interfaces/    |     76.19 |        50 |     55.56 |     76.19 |
      tdd.js                              |     76.19 |        50 |     55.56 |     76.19 |
   node_modules/intern/lib/reporters/     |     60.87 |        35 |     57.14 |     60.87 |
      console.js                          |     60.87 |        35 |     57.14 |     60.87 |
   node_modules/intern/node_modules/chai/ |     34.23 |      5.02 |     23.76 |     35.49 |
      chai.js                             |     34.23 |      5.02 |     23.76 |     35.49 |
   src/                                   |     71.43 |     33.33 |     83.33 |     71.43 |
      FTPTest2.js                         |     71.43 |     33.33 |     83.33 |     71.43 |
------------------------------------------+-----------+-----------+-----------+-----------+
All files                                 |     39.36 |      8.64 |     29.92 |     40.64 |
------------------------------------------+-----------+-----------+-----------+-----------+
<script hangs here...>

尽管记录了测试失败,但两个脚本似乎都在执行结束时挂起。

我做错了什么,以及如何改进脚本以更好地使用实习生?

1 个答案:

答案 0 :(得分:1)

您提供的代码至少有两个问题。

问题一:

    // ...
    dfd.reject.bind(dfd);
    // ...

此代码没有做任何事情。它只是创建并立即丢弃new bound function。它应该调用拒绝:dfd.reject(err)。请注意reject的参数是一个Error对象,而不是一个字符串。

问题二:

           ftp.ls('i_do_not_exist', dfd.rejectOnError(function(err, res) {
                console.log('Ftp result: err: ', err, ' res: ', res);
                if (err) {
                    console.error('Error in ls, failing FTP test.');
                    throw err;
                }

                console.log('ls succeeded.');

                // Got to do a raw quit when success or fail
                ftp.raw.quit(dfd.callback(function(err, data) {

如果需要调用quit而不管错误条件(根据代码注释),则此代码不是。之前会抛出几行错误。如果代码没有清理它创建的所有套接字,Node.js将永远不会退出。

此外,OP中链接的“intern-wiki”存储库不是官方文档。我有兴趣了解你是如何降落在那里的。 correct documentation链接到旧维基和主页。