Машинопись и асинхронная инициализация вне транспортира it

#typescript #promise #async-await #stream #protractor

#машинопись #обещание #асинхронное ожидание #поток #транспортир

Вопрос:

Я прочитал тестовую конфигурацию из CSV файла с csv-parser , который ведет себя асинхронно. Когда я оборачиваю анализатор в обещание и использую его в своем асинхронном it тестовом примере с помощью await, данные конфигурации разрешаются… за пределами «it» это не разрешено, поскольку describe поддерживает no async и module: commonjs не допускает ожидания верхнего уровня. Данные конфигурации содержат тестовые данные, которые используются для выполнения тестового примера «it» в цикле с различными параметрами. Итак, мне нужен способ:

  1. разрешите обещание вне «it», чтобы получить данные конфигурации ИЛИ
  2. чтобы найти способ дождаться завершения csv-parser потока / канала / включения, прежде чем возвращать данные конфигурации.
 export function initCountryMatrixFromCsv() {
  return new Promise <Map<string, ShopFunction>>((resolve, reject) => {
    const countryShopFunctions = new  Map<string, ShopFunction>();
    countryShopFunctions.set(ALL_FUNCTIONS, new Map<string, ShopFunction>());
    const fs = require('fs');
    const csv = require('csv-parser');

    const parsedCsv = [];

    // behaves async... returns imediately and without the promise countryShopFunctions map is not filled:
    fs.createReadStream(__dirname   '/country_matrix.csv')
      .pipe(csv({ separator: ',' }))
      .on('headers', async (headers) => {
            // some header inits
         }
      )
      .on('data', async (data) => await parsedCsv.push(data))
      .on('end', async () => {
        // init configuration in countryShopFunctions
      });
  }); 

 describe('E2E-I18N-CMX: test country matrix', () => {
    // a promise... await not alowed here
    const matrix = initCountryMatrixFromCsv(); 
    
    // not possible since matrix is a promise
    matrix.forEach((shopFunction, roleName) = > {
        it('Test '   role, async (){
            // perform test with shopFunction params
            // first place to resolve the promise ... but i need it outside the it
            const matrix2 = await initCountryMatrixFromCsv(); 
        });
    });
}); 

Я попробовал несколько вариантов с обещанием и без него, но все закончилось пустой картой, когда я не использую обещание с ожиданием.

Ответ №1:

Я предполагаю, что вы используете Protractor с Jasmine (хотя на самом деле это не имеет большого значения).

Jasmine попытается разрешить тестовые примеры до initCountryMatrixFromCsv того, как будет разрешен ваш фактический метод. Причина этого проста: он должен знать, сколько тестов существует в рамках его настройки.

Я столкнулся с той же проблемой в наших тестах, и решение состояло в том, чтобы прочитать синхронизацию CSV-файла.

Для этого я использовал пакет csv-load-sync npm, а затем прочитал файл:

 import * as fs from 'fs';
import * as loader from 'csv-load-sync';
import * as path from 'path';

readTestDataCsvSync() {
    const filePath = path.join(__dirname, 'TestData.csv');
    try {
      if (fs.existsSync(filePath)) {
        return loader(path.join(__dirname, 'TestData.csv'));
      }
    }
    catch (err) {
      throw new Error(`Couldn't load the test cases CSV file: ${err}`);
    }
  }
 

Теперь вы можете просто выполнять свои тесты, как и раньше:

 describe('E2E-I18N-CMX: test country matrix', () => {
    const matrix = readTestDataCsvSync(); 
    
    matrix.forEach((shopFunction, roleName) = > {
        it('Test '   role, async (){
            // your test
        });
    });
});
 

Ответ №2:

Поместите функцию инициализации в блок beforeAll /beforeEach . Затем матрица доступна в каждом ит

 describe('your test', () => {
  let matrix2;

  beforeAll(async () => {
    matrix2 = await initCountryMatrixFromCsv();
  });

  it('my test', () => {
    expect(matrix2).toBeTruthy(); // do more verifications ...
  });
});
 

Также убедитесь resolve , что обещание в функции. Я думаю, вы хотите, чтобы это разрешилось в on (‘end’)

Комментарии:

1. да, я разрешаю обещание в on (‘end’). Я также уже пробовал beforeAll / beforeEach и внутри «it» он разрешен, но не за пределами «it». Поэтому я не могу использовать matrix.forEach вне it.