11

I am trying to run data-driven testing using csv file in protractor:

I have created a read csv promise module:

    let readSync = async function (path1) {
    console.log(path1)
      const csv = require('csv-parser')
      const fs = require('fs')
      const results = [];
    
    
      function getIdRequest(path2) {
        console.log(path2)
        return new Promise((resolve, reject) => {
    
         
          fs.createReadStream(path2)
            .pipe(csv(path2))
            .on('data', (data) => results.push(data))
            .on('end', () => {
              resolve(results);
            })
        });
      }
      console.log(path1)
      return getIdRequest(path1);
    }
    // to get the request body 
    
      module.exports = readSync;

Now i am calling the same from my test file:

    let readCSV = require('../commons/readSync.js');
    
    describe('Validate stage 1 behaviour', function () {
    
      let testdata=await readCSV(browser.params.testFile);
    
      for (let a of testdata) {
     
        it('test {Regression} {Sanity} {Sanity}', async function () {
          //check title
          console.log("inside")
          await mainPage.goto();
          await mainPage.clickElement('inputField')

But i cannot use await inside describe, so I tried using :

    let readCSV = require('../commons/readSync.js');   
    
    describe('Validate stage 1 behaviour', function () {
    
      readCSV(browser.params.testFile).then(function(testdata){
    
      for (let a of testdata) {
        console.log("outside")
        it('test {Regression} {Sanity} {Sanity}', async function () {
          //check title
          console.log("inside")
        });
    
      }

but in this, 'it' function is not getting executed, its printing only 'outside'

Challenges

  1. Cannot use await inside describe as it accepts only synchronous function

  2. Cannot use promise.then(describe(function(){} because 'IT' and 'Describe' is not recognized when called inside the callback. I get 0 spec executed message.

  3. Tried calling the testdata in before hooks but this also fails as the for loop is outside the It block . So, the compiler tries to run for loop even before 'before hook' is executed .

  4. I tried using nested describe and calling await testdata in before each and before all . But even that fails with the same reason , refer: https://stackoverflow.com/q/48344674/6793637

Questions:

  1. So is there a better way to run data driven testing using csv in protractor ?

  2. Is there a way to synchronously make the suggest solution work?

  3. Why is describe or IT block doesn't work inside a callback ? Eg Promise.then(describe()) won't execute describe

3

2 Answers 2

9

Hi i found another csv module : csv-parse : https://csv.js.org/parse/ (Its used in postman)

const parse = require('csv-parse/lib/sync');

Use this module for data-driven testing instead of below-step

Below method is deprecated:

Made it work.

Please suggest any better ways if anyone knows:

Solution:

Install system-sleep module:

npm install system-sleep

.............Updated..........

Now run your tests as:

let testdata=readSync(browser.params.testFile);
var sleep = require('system-sleep');

describe('Validate dfsfdsf 1 behaviour', function () {

//Assign the value when promise gets resolved
//This is asynchronous so we will add a implicit wait
testdata.then(function(b){testdata=b}); 

//sleep till the test resolves
  while(typeof testdata.then === 'function'){
    sleep(1)
  }     

  for(let a of testdata){
    it('test {Regression} {Sanity} {Sanity}', async function () {
      console.log(a)
    });
  }

Update:

https://www.npmjs.com/package/csv-parser-sync-plus-promise

Happy days guys I have created an npm package for this, anyone is free to use it

Now data driven testing is as simple as :

let parser= require('csv-parser-sync-plus-promise');
let testdata = parser.readCsvSync(browser.params.testFile);



describe('Validate dfsfdsf 1 behaviour', function () {


  for(let a of testdata){
    it('test {Regression} {Sanity} {Sanity}', async function () {
      console.log(await parser.readCsvPromise(browser.params.testFile))
    });
  }
9
  • 1
    Sleep should never the solution, why not: testdata.then(function(b){ for(let a of b){ // code here}}); Commented Jan 24, 2020 at 8:58
  • 1
    Or use async/await Commented Jan 24, 2020 at 8:59
  • @NielsvanReijmersdal he please see my question , I tried that , but it and describe block is not being identified inside callback function
    – PDHide
    Commented Jan 24, 2020 at 8:59
  • @NielsvanReijmersdal async doesn't work inside describe . Describe block supports only synchronous function . I can't keep it inside before hooks also because the for loop is outside the 'it' block and so will get executed before the 'before' hook get executed
    – PDHide
    Commented Jan 24, 2020 at 9:02
  • Your example is missing async on the describe function, e.g. describe('Test Suite 1', async function(){ let testdata = await asyncMethod() Commented Jan 24, 2020 at 9:02
0

A simpler approach using map function: (Considering testArray is an array of objects)

var testParams =testConfig.testArray;   
testParams.map(function(testdata) { 

   it('write your test here', function() { 
         console.log('Username: ',         
          testData.username); 
    });
});
1
  • Hi the issues here is of getting the test array :) , if we get an array , then map or for or while any loop works .but the csv parse returns a promise that resolves to a array
    – PDHide
    Commented Jan 25, 2020 at 11:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.