0

I have one forEach that does a bunch of tests. If a test passes I store a value in array. I then want to execute a second forEach based on that array. So if all tests fail, second forEach doesn't run at all, if one or more passes, it runs tests for each value in the array. However, the forEach always takes the initial value, its always seen as empty regardless of test results. Is it possible to delay creating the second forEach until the first is finished? So it will get the actual value of the dynamic array? Or is this not possible?

Here is the structure (some non-important stuff omitted):

let amount;
const sent = [];

constants.assets.forEach((asset) => {
    describe(`Send ${asset}`, function() {
        const suite = this.title;
        let driver = null;

        // Test Hooks

        before(async function() {
            // runs before all test cases
            this.timeout(installTimeout);
            log.out('Creating driver');
            try {
       
                log.out('Start Testing');
            } catch (error) {
                log.out('Error at before hook ' + suite + ': ' + error);
                assert.fail(error);
            }
        });

        after(async function() {
            // runs after all tests cases
            this.timeout(installTimeout);
            log.out('Destroying driver');
            try {
                await mobileDriver.destroyDriver(global.test.driver);
                log.out('End Testing');
            } catch (error) {
                log.out('Error at after hook ' + suite + ': ' + error);
                assert.fail(error);
            }
        });

        beforeEach(async function() {
            // runs before each test case
            await log.initialize(suite, this.currentTest.title);
            log.out("Start Test: " + suite + "/" + this.currentTest.title);
        });

        afterEach(async function() {
            // runs after each test case
            log.out("End Test: " + suite + "/" + this.currentTest.title);
        });

        // Test Cases

        it(test.name('Login'), async function () {
            this.timeout(standardTimeout);
        });

        it(test.name(`Send ${asset}`), async function () {
            this.timeout(standardTimeout);
       
            sent.push(asset)
        });
    });
});


sent.forEach(function (asset) {
    if (sent.includes(asset)) {
        describe(`Send ${asset} Transaction Verification`, function() {
            const suite = this.title;
            let driver = null;

            // Test Hooks
    
            before(async function() {
                // runs before all test cases
                this.timeout(installTimeout);
                log.out('Creating driver');
                try {
                
                    log.out('Start Testing');
                } catch (error) {
                    log.out('Error at before hook ' + suite + ': ' + error);
                    assert.fail(error);
                }
            });
    
            after(async function() {
                // runs after all tests cases
                this.timeout(installTimeout);
                log.out('Destroying driver');
                try {
                    await mobileDriver.destroyDriver(global.test.driver);
                    log.out('End Testing');
                } catch (error) {
                    log.out('Error at after hook ' + suite + ': ' + error);
                    assert.fail(error);
                }
            });
    
            beforeEach(async function() {
                // runs before each test case
                await log.initialize(suite, this.currentTest.title);
                log.out("Start Test: " + suite + "/" + this.currentTest.title);
            });
    
            afterEach(async function() {
                // runs after each test case
                log.out("End Test: " + suite + "/" + this.currentTest.title);
            });
    
            // Test Cases
        
            it(test.name('Login'), async function () {
                this.timeout(standardTimeout);
              
            });
         }
    });
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
George
  • 322
  • 1
  • 6
  • 25
  • `describe` and `it` don't *run* a test, they only tell the test framework what tests are available. You cannot do this, and you shouldn't define conditional tests anyway. At best, define tests that can always run but sometimes do nothing. – Bergi May 04 '21 at 13:21
  • These tests do run, all test files in the project are setup this way. – George May 04 '21 at 13:35
  • Sure, but they don't run from within the (synchronous!) `describe` and `it` calls. – Bergi May 04 '21 at 15:07
  • I don't really follow, project was setup this way and tests run fine, one after the other. I'm asking about forEach and dynamic values. – George May 04 '21 at 16:15
  • What test framework are you using? – Bergi May 04 '21 at 16:25
  • The problem is not with the `constants.assets.forEach(`, it is the usage of `sent` outside of the tests that are executed asynchronously. Just like https://stackoverflow.com/q/23667086/1048572. – Bergi May 04 '21 at 16:26
  • Mochajs. The second test suite doesn't run until after first is complete but they do initialize at the same time which causes the issue I'm having, not sure a way around it. – George May 04 '21 at 16:34
  • There is no way around it, you must initialise all the tests, using the same loop. Then, you can however [skip each of the tests dynamically](https://stackoverflow.com/a/32820119/1048572) based on the results of the previously executed tests. – Bergi May 04 '21 at 16:38

1 Answers1

1

When Mocha prepares to run your tests, it goes through your code and pulls out all the describe and it calls it finds to assemble test suites, while not triggering the tests themselves.

Once all of the tests have been located and assembled into test suites, the tests are executed in the order they got queued.

In the code you have provided, the tests are queued up for each asset in your array, as you expect and observe. However during the setup phase, the array sent is empty, which means that none of the tests defined in it's callback are ever added to mocha's test queue. Once testing begins, entires will be added to the sent array, but they won't ever be used.

samthecodingman
  • 23,122
  • 4
  • 30
  • 54