【问题标题】:Intern test of async service (ftp) does not fail test on error异步服务 (ftp) 的实习生测试不会因错误而失败测试
【发布时间】:2015-03-03 05:42:33
【问题描述】:

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

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

这些脚本故意尝试“ls 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...>

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

我做错了什么,还有什么方法可以改进脚本以更好地使用实习生?

【问题讨论】:

    标签: node.js asynchronous tdd intern


    【解决方案1】:

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

    问题一:

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

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

    问题二:

               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 而不管错误情况如何(根据代码 cmets),则不需要此代码。前面几行抛出了一个错误。如果代码没有清理它创建的所有套接字,Node.js 将永远不会退出。

    此外,OP 中链接到的“intern-wiki”存储库不是官方文档。我很想知道你是如何到达那里的。 correct documentation 链接到旧 wiki 和主页。

    【讨论】:

    • 谢谢科林。你说的完全正确,非常感谢。整个“dfd.reject.bind”的情况真的让我很困惑,神秘的“//确保没有引发 HTTP 错误。dfd.reject.bind(dfd);”我从示例代码中获取的内容对我来说毫无意义。至于 FTP 套接字,你又是对的,即使 ls 失败,也调用 quit 然后在其回调中失败测试,​​效果很好。那个文档链接是谷歌的脑残,我只是在上面发布了错误的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    相关资源
    最近更新 更多