44
votes

I am running Karma/Jasmine/Angular 2.0 tests on my development box. Just recently, Jasmine on my development box decided to start running my tests three times. Yes, exactly three times, every time.

On the first run, everything passes as expected. However, on the second and third pass, all of the same things fail. It always acknowledges that there are 7 tests, but runs 21, and 10 fails (first-grade math out the window)????

This also fails on Travis with SauceLabs. (Note: That links to an older build with 3 tests, but ran 9, and 5 fail???)

I have a screenshot, karma.conf.js file, and one suite which started this whole thing. Any help with be greatly appreciated.


Culprit [TypeScript] (Remove this and problem solved on my dev box):

Full source

describe('From the Conductor Service', () => {
    let arr: Array<ComponentStatusModel> = null;
    let svc: ConductorService = null;
    
    beforeEach(() => {  
        arr = [/* Inits the array*/];
        svc = new ConductorService();
    });

    describe('when it is handed a container to hold objects which need to be loaded', () => {
        // More passing tests...
    
        /// vvvvv The culprit !!!!!
        describe('then when you need to access the container', () => {
            beforeEach(() => {
                svc.loadedContainer = arr;
            });
        
            it('it should always be available', () => {
                assertIsLocalDataInTheService(arr, svc.loadedContainer);
            });
        });
        /// ^^^^^ End of culprit !!!!!
    });

    // More passing tests...
});

Failing Tests:

Tests are ran three times

Browser Screenshots:

Not sure if this is related, but before all of the errors happen, the Jasmine call stack is smaller (left, observe scrollbar). After the errors start, the stack just gets bigger with repeating calls to the same functions (right, observe scrollbar).

Jasmine Call Stack

Suite Stack is Wrong:

In my test, the Nanobar and Conductor spec files are totally separate. However, you can see the suites array includes stuff from the Nanobar and Conductor specs. Somehow Jasmine mashed these two spec files together (after everything started failing), and resulted in my describe() statements not making any sense when published to the console.

Jasmine Suite Stack

Simplified karma.conf.js:

Full source

module.exports = function (config) {
    config.set({
        autoWatch: false,
        basePath: '.',
        browsers: ['Chrome'],
        colors: true,
        frameworks: ['jasmine'],
        logLevel: config.LOG_INFO,
        port: 9876,
        reporters: ['coverage', 'progress'],
        singleRun: true,
        
        coverageReporter: {
            // Code coverage config
        },

        files: [
            // Loads everything I need to work
        ],

        plugins: [
            'karma-chrome-launcher',
            'karma-coverage',
            'karma-jasmine'
        ],

        preprocessors: {
            'app/**/*.js': ['coverage']
        },

        proxies: {
            // Adjust the paths
        }
    })
}
3
Your samples don't exactly show what the issue is but 99% of the time when I have issues like this it is because one or more of the tests have a "side effect". Basically tests need to be written so that the beforeEach sections build everything from scratch. Then each test can be run independently and in any order. If you do need to change a global or other similar variable use an afterEach to tear that down again. Hope that helps a bit! - drew_w
@drew_w I really appreciate your advice. Would it be more helpful if I included the entire spec for clarity's sake? - Oliver Spryn
To be honest you probably have posted sufficient details for the core of the problem. Your best bet at getting a more precise answer is to post a fiddle or similar demonstrating the issue. I realize that takes time but it certainly would help. - drew_w
@drew_w I actually have this project on GitHub. If it is helpful, here is the spec: git.io/v2Kat (link also posted above) - Oliver Spryn
I've just encountered the same problem, and noticed that it seems to go away if a new pipe is instantiated in the test or in a beforeEach before the test (such as importing an external library and instantiating it before each test). - A. Duff

3 Answers

1
votes

Can you try refreshing your browser in your first assertion in each of your test files? Try this:

browser.restart();

I had the same problem and this fixed it for me.

0
votes

The first thing is these test run randomly. If you pass some data in any test case if you think you can resue that it is not possible.

You have to declare the data in before each so all test cases get data. All test cases run independently.

If you are using array or object you must have to use this after deep cloning because array and object works on the reference. If you manipulate any value it will also change the original array.

In most of the cases if the test fails there may be an error of data you are passing in test cases.

0
votes

I would try to debug this and pinpoint the exact cause. Usually happens when I have redirection code or any reload code inside the functions I'm testing.

  • You can try adding an f to the prefix of describe and it (i.e. fdescribe and fit)