Get help with testing, discuss unit testing strategies etc.


Post by nuridesengin »

Hello there.

I'm trying to write first Unit test through Testing CMD App guide. I've created a test file but it can not find declaration for MyApp to go. Here is code snippet of Unit test;

010_globals.t.js
describe('MyApp Globals', function(t) {
    t.ok(MyApp.Globals, 'Globals.js is here');

    t.describe('getStatusDesc() method', function(t) {

        t.it('should be a function', function(t) {
            t.expect(typeof MyApp.Globals.getStatusDesc).toEqual('function');
        });

        t.it('should return a string', function(t) {
            t.expect(typeof MyApp.Globals.getStatusDesc()).toEqual('string');
        });
    });

});
The error occurs during t.expect action and says;
Test threw an exception
ReferenceError: MyApp is not defined
    at line 2, character 10, of 01-unit-tests/010_globals.t.js
I've researched web for solution for last 2 days and configured test suite with that opinions as you'll see below but still keep getting this error :(
  • 1. Used loaderPath on harness.configure:
    loaderPath: {
    'MyApp': 'app'
    },
  • 2. Used preload on harness.configure:
    preload : [
    'app/Globals.js'
    ]
  • 3. Used ok method in test file as you see above
Depends on those configurations still I can not call my Globals.js and methods inside of the file to test! What am i doing wrong here?

Post by nickolay »

The guide you mentioned suggest to use

pageUrl : '../index.html?unittest',

And modifying main app file "app.js" to not start the app during unit testing. Try that?

Post by nuridesengin »

Dear nickolay actually I do not want to touch application files such as app.js or application.js is there any other way to call methods in app folder?

Post by nickolay »

If not using "pageUrl" you'll have to manually setup the "preload" config, which can be tricky for cmd app. And if not modifying "app.js" - the app will be started right away, which is not what we want for unit testing. The suggested modification is very minimal - should be safe for any project.

If you are still not convinced - then just use the "preload" config to specify what files should be loaded before the test. Having the "loaderPath" set, you can also use "requires" config: https://www.bryntum.com/docs/siesta/#!/ ... g-requires

Post by nuridesengin »

Dear nickolay, I'm following Mastering Ext JS book and launch function is defined inside another class. Therefore I couldn't configure app.js within mainView config accordingly couldn't configure pageUrl on harness. Here is a snippet of launch method;
launch: function () {
        var me = this;
        var task = new Ext.util.DelayedTask(function () {
            me.splashscreen.fadeOut({
                duration: 1000,
                remove: true,
                listeners:{
                    afteranimate: function (el, startTime, eOpts) {
                        if(!MyApp.utils.LoginAuth.tokenValidate()){
                            Ext.widget('login-dlg');
                        }
                        else{
                            Ext.widget('mainport');
                        }
                    }
                }
            });
        });
        task.delay(1000);
    }
So I tried your other advices but somehow they did not work as well and still says:
ReferenceError: MyApp is not defined
    at line 6, character 29, of 01-unit-tests/010_globals.t.js
* I've declared loaderPath on harness.configure and hopefully I'm doing correct mapping :/ Here is file-directory image @ https://prnt.sc/hqgc9f
loaderPath: {
        'MyApp': '../../app'
    }
* also configured harness.start with preLoad and requries configs:
var localApp = 'https://localhost:1841/MyApp/';

harness.start(
    {
        group   : 'Unit Tests',
        runCore : 'sequential',
        enableCodeCoverage : false,
        items   : [
            {
                title           : 'Globals',
                // pageUrl         : '../../index.html',
                hostPageUrl     : localApp,
                url             : '01-unit-tests/010_globals.t.js',
                preload         : [
                    'https://cdnjs.cloudflare.com/ajax/libs/extjs/6.2.0/ext-all.js',
                    '../../app/Globals.js'
                ],
                requires: ['MyApp.Globals']
            }
        ]

Post by nickolay »

When you use "pageUrl" ('hostPageUrl' is an old, deprecated name of this config), you usually don't want to use "preload" and "requires". "pageUrl" will open a whole html page, just like a tab in the browser. That page, in turn, already contains <script> and <link> tags for loading required resources. So here you are probably double loading the "Globals.js" file for example. First time it will be loaded as part of the "pageUrl" loading. Second time it will be loaded as "preload" config. Same thing about "ext-all.js"

Check the Network tab in the debugger for the 404 errors.

The idea of testing cmd app, as described in the guide is as follows:
1) You add a special query parameter to the application url: `unittest`. So full url will look like: https://localhost:1841/MyApp/?unittest
This parameter will indicate for the app, that it has been opened from the testing environment.
Inside the app, you can check for the presence of this parameter with `location.search.match('unittest')`
2) In the place, where your application launches (normally app.js file or another file), you add a check for `location.search.match('unittest')`. If it is true, then _do not start_ the app.
3) So the app won't be started, but the whole environment will be the same as normal Sencha Cmd environment.
4) Then, in your test, you can require needed classes and instantiate / test them .

Post by nuridesengin »

Dear nickolay somehow still I get the Reference error. As you mention I've disabled hostPageUrl, changed to 'pageUrl : '../../index.html?unittest'' and I can see on Chrome's network tap, its loading with 200-OK status. As well disabled preload & requires configs.

I've tried define location.search.match('unittest') in launch() method with an if .. else statement;
launch: function () {
        var me = this;
        if (location.search.match('unittest')) {
          
        } else {
            var task = new Ext.util.DelayedTask(function () {
                me.splashscreen.fadeOut({
                    duration: 1000,
                    remove: true,
but this configuration did not work as well. So finally I've deleted launch() method configurations and stated mainView config on app.js ;
mainView: location.search.match('unittest') ? null : 'MyApp.view.main.MainPort'
but still still It says ReferenceError: MyApp is not defined. I've tried to disable & able loaderPath config but did not work... I can not make unittest working =(

Post by nickolay »

Well, try to figure out why it happens? The exception says there's no "MyApp" global. Is it defined in your app (on the page that is specified with `pageUrl`)?

If you will prepare a self-contained zip archive demonstrating the problem I can take a look as well.

Post by nuridesengin »

well I've tried so many different aspect to overcome to error but I couldn't be success.
Here is some snippets of app in zip file. That'll pleasure if you could have a look.
siesta.zip
demo-app
(5.83 KiB) Downloaded 210 times

Post by nickolay »

Please zip a whole folder (may be w/o Ext since its huge). Make sure the zip actually demonstrates the problem you experience (unpack it to different location and verify).

I took a quick look and see that MyApp.Globals singleton is defined in the file app/Globlas.js - perhaps thats why app can't load it? (extra "l" in file name).

Post Reply