【问题标题】:What are the recommended ways to debug Worklight applications?调试 Worklight 应用程序的推荐方法是什么?
【发布时间】:2013-04-04 07:00:42
【问题描述】:

我发现修复特定于我的应用的 iOS 部分的问题非常缓慢。我想知道当浏览器调试器不可用时调试 Worklight 应用程序的推荐方法。

特别是,我正在处理仅适用于 iOS 和 Android 的 WL.JSONStore 问题。我无法使用浏览器调试器查看发生了什么。当我执行 WL.Logger.debug() 语句时,Xcode 控制台中没有显示任何内容,iPad 模拟器控制台 (Cordova) 仅显示几行。本周也有一段时间没有在任何地方打印输出。

我也下载并安装了 Weinre,但它的控制台中似乎没有显示任何打印语句,而且通常我只是看不到有关我需要的区域的信息。

提前感谢您的建议。

【问题讨论】:

    标签: debugging ibm-mobilefirst jsonstore


    【解决方案1】:

    通用 Worklight 5.0.6 调试

    Worklight 5.0.6 上 JSONStore 的调试提示

    • jsonstore.js 和您的代码([app-name].js 等)中尝试console.log('message')WL.Logger.debug('message')。输出应显示在 Xcode 的控制台和 Android 的 LogCat 中。

    • 重置模拟器或模拟器和/或致电WL.JSONStore.destroy()

    • 确保您在受支持的环境中运行:

      • Android >=2.2 ARM/x86 模拟器或设备
      • iOS >=5.0 模拟器或设备
    • 尝试关闭加密(即不要将密码传递给WL.JSONStore.initWL.JSONStore.initCollection)。

    • 查看 JSONStore 生成的 SQLite 数据库文件。这仅在加密关闭时有效。

      • 安卓:

          $ adb shell
          $ cd /data/data/com.[app-name]/databases/wljsonstore
          $ sqlite3 jsonstore.sqlite
        
      • iOS

          $ cd ~/Library/Application Support/iPhone Simulator/6.1/Applications/[id]/Documents/wljsonstore
          $ sqlite3 jsonstore.sqlite
        

      尝试使用.schema 查看搜索字段并使用SELECT * FROM [collection-name]; 选择数据。要退出sqlite3,请输入.exit。以this StackOverflow question 为例。

    • (仅限 Android)启用详细 JSONStore。

        adb shell setprop log.tag.jsonstore-core VERBOSE
        adb shell getprop log.tag.jsonstore-core
      
    • (仅限 iOS >=6.0 和 Safari >=6.0)尝试使用JavaScript debugger。在jsonstore.js 内设置断点。有用的线路:

      • 桥接本机代码:

          cdv.exec(options.onSuccess, options.onFailure, pluginName, nativeFunction, args);
        
      • Native 代码返回的成功回调:

          deferred.resolve(data, more);
        
      • Native 代码返回的失败回调:

          deferred.reject(new ErrorObject(errorObject));
        
    • 编写适当的测试(单元、功能、集成——获得测试覆盖率)。下面是一个模板,它使用QUnitSinon.js 创建一个沙盒环境,您可以在其中测试 JSONStore 如何处理不同类型的数据/调用:

        <!DOCTYPE HTML>
        <html>
      
        <head>
            <title>JSONStore Test App</title>
            <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css">
            <script src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
            <script src="http://sinonjs.org/releases/sinon-1.6.0.js"></script>
            <script>
                //QUnit configuration flags, no need to change it.
                QUnit.config.requireExpects = true;
            </script>
        </head>
      
        <body id="content" style="display: none;">
      
            <!-- Test results will be appended to the div below, no need to make changes here. -->
            <div id="qunit"></div>
      
        <script>
      
        //Start Worklight
        WL.Client.init({connectOnStartup : false});
      
        //Hook into the deviceready event
        document.addEventListener("deviceready", onDeviceReady, false);
      
        //onDeviceReady will be called when JSONStore/Cordova is ready
        function onDeviceReady () {
      
            //Auto executing function that holds the test
            (function (jQuery) { //The variable jQuery is usable inside.
      
                //Mock WL.Client.invokeProcedure using a Stub.
                //This is only useful if you need to link a Worklight Adapter
                //to a JSONStore collection to reproduce your issue or bug.
                //API Doc: http://sinonjs.org/docs/#stubs
                var fakeAdapter = sinon.stub(WL.Client, "invokeProcedure", function (invocationData, options) {
      
                    //DO NOT Create a real adapter, just mock the reponse here if it's relevant to the bug.
                    var ADAPTER_RESPONSE = {invocationResult: {fakeKey: [{fn: 'carlos'}, {fn: 'mike'}]}};
                    options.onSuccess(ADAPTER_RESPONSE);
                });
      
                //[**Explain your test here**]
                var EXPECTED_ASSERTIONS = 2; //every assertion is a deepEqual below.
                asyncTest('[**Meaningful title here**]', EXPECTED_ASSERTIONS, function () {
      
                    //Destroy first to make sure we don't depend on state
                    WL.JSONStore.destroy()
      
                    .then(function () {
      
                        //[**Start writting your test here**]
                        //The test below is an example, it does the following:
                        // - Initializes a collection linked to a fake adapter (see stub above).
                        // - Checks if initialization worked by checking the collection name.
                        // - Loads data from the fake adapter (see stub above).
                        // - Checks if load worked by checking the number of documents loaded.
      
                        var collections = {
                            col1 : {
                                searchFields : {fn: 'string'},
                                adapter : {name: 'fakeAdapter',
                                    load: {
                                        procedure: 'fakeProcedure',
                                        params: [],
                                        key: 'fakeKey'
                                    }
                                }
                            }
                        };
      
                        return WL.JSONStore.init(collections);
                    })
      
                    .then(function (response) {
      
                        //Prep for your assertion
                        var ACTUAL_VALUE = response.col1.name;
                        var EXPECTED_VALUE = 'col1';
                        var COMMENT = 'Checking for the right collection name';
      
                        //Do your assertion using deepEqual
                        //API Doc: http://api.qunitjs.com/deepEqual/
                        deepEqual(ACTUAL_VALUE, EXPECTED_VALUE, COMMENT);
      
                        return WL.JSONStore.get('col1').load();
                    })
      
                    .then(function (response) {
      
                        //Prep for your assertion
                        var ACTUAL_VALUE = response; //load returns number of documents loaded
                        var EXPECTED_VALUE = 2; //two documents are returned by the fake adapter (stub)
                        var COMMENT = 'Checking if load worked';
      
                        //Do the assertion using deepEqual
                        deepEqual(ACTUAL_VALUE, EXPECTED_VALUE, COMMENT);
      
                        start();//call start() after you finish your test succesfully
                    })
      
                    .fail(function (error) {
      
                        deepEqual(false, true, 'Failure callback should not be called' + error.toString());
                        start();//call start() after you finish your test with a failure
                    });
      
                });
      
            }(WLJQ)); //end auto executing function that holds the test
      
        } //end wlCommonInit
        </script>
      
        </body>
        </html>
      

    上述代码的预期输出:

    旁注:这是针对特定开发人员的关于 PhoneGap/Cordova 工作流程的general article。有一部分调试,只是基于浏览器。其中一些也适用于 IBM Worklight 开发。

    【讨论】:

    • 感谢您的详尽回答。为了澄清,将 WL.Logger.debug() 更改为 console.log() 不会改变我的代码。 iOS 模拟器控制台仍然只显示一些 stmts,它对 Xcode、Eclipse 和 Weinre 是不可见的。阅读数据库并将语句放入 jsonstore.js 是明智的建议。就像使用 Safari js 调试器单步执行 jsonstore.js 一样。
    【解决方案2】:

    cnandreu 在这里提供了很好的提示。尽管如此,能见度还是很差,这些方法并没有真正解决我的问题。我还想建议我发现在我的项目中最有用的东西(除了 WL.Logger.debug() 无处不在):

    • JSConsole 已经不可或缺 (http://jsconsole.com/)。实际上,我实际上并没有像预期的那样使用它。但是,我发现它的启动警告消息对 WL.Logger.debug()(和 console.log())有作用,使语句能够实际打印到控制台,这样我就可以看到我在做什么。

    • 在 iOS 6 中,Mac 上的 Safari 允许您检查连接设备的 DOM。它相当有用,特别是对于仅在 iOS 上本机运行时行为不端的混合 UI 问题。否则我觉得它不是很有帮助。更多信息请访问https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/DebuggingSafarioniPhoneContent/DebuggingSafarioniPhoneContent.html

    • 我一直在使用的最有用的技术是将状态消息写入 UI。是的,这是一种丑陋的史前做事方式,但其他一切——包括 80 年代到控制台的错误打印语句——都惨遭失败。这是我所做的(使用 Dojo 和 JavaScript):

      var v = dom.byId('audio_status'); if (v) { v.innerHTML += "recording file ["+filename+"]"; }

    其中audio_status 是显示调试内容的DIV 的ID

    这东西很丑,但至少我们可以看到一些东西

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-06
      • 2011-11-04
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 2015-11-23
      • 1970-01-01
      相关资源
      最近更新 更多