【问题标题】:Defining dynamic Array in Typescript?在 Typescript 中定义动态数组?
【发布时间】:2020-05-30 11:11:50
【问题描述】:

我有一个要求,我想在 n 次循环中读取特定值 x(每次自动生成)。现在,我想存储这些自动生成的 x 值,以便以后可以使用它们并对其进行迭代以执行我的测试(量角器)。

我想做的方法是使用let list: string[] = []; 创建一个数组。现在,我在每次迭代中使用list.push[x]; 将值推送到我定义的列表中。在循环结束时,期望在我的list 数组中获得具有 n 个 x(string) 值的数组。为了验证,我在每次迭代中都做了console.log(list);,我可以看到这些值被推送到定义的list中。

稍后,在我的代码中,如果我尝试使用 let item = list[0]; 访问这些元素,我将获得 undefined 值。

我认为我需要将数组初始化为具有默认值的特定大小,然后在循环中稍后修改它们。但是,作为 TypeScript 的新手,我无法找到有关如何执行此操作的解决方案。请帮助,TIA!

这里是下面的sn-p:

    const tests = [
{type: 'admin', id='', uname='foo', pass='bar'},
{type: 'super', id='', uname='foo1', pass='bar'},
{type: 'normal', id='customId', uname='foo', pass='bar'}
];

let list: string[] = [];
// let list = [         //this is the final list that i got from the console.log(list);
// 'QR417msytVrq',
// 'V0fxayA3FOBD',
// 'QnaiegiVoYhs'];

describe(`Open Page `, () => {
  //Code to get to the page

  beforeAll(async () => {
    //initialize page objects

  });

  describe(`Login User `, async () => {
    tests.forEach(test => {
      it(` should login user with `+test.type, async () => {

        //....
        //....


        // On Success
        const myId = userPage.getUID().getText();

        list.push(myId);
        console.log(list);
        console.log(list.length);
      });
    });
  });


  describe(`Delete User`, async () => {

    // describe(`Confirmation `, async () => {
    console.log(list);
    // list.forEach(item => {       //this code doesn't gets executed and wasn't giving any error, so, commented out and tried to access the first element which is undefined.
      let item = list[0];
      console.log(item);            //getting undefined value here. 
      it(` should select and Delete the User having id as ` + item, async () => {
        //code to remove the user having id as item.
      });
    // });
  });
});

【问题讨论】:

  • 我猜这是因为您没有正确使用推送功能。在您的示例中,您使用的是list.push[x],但是,您可能正在寻找iten.push(x)。后者将添加一个元素做数组。要么就是你的代码中有其他东西正在重置数组。如果您发布代码的相关部分可能会有所帮助。
  • 添加了我正在尝试做的事情的 sn-p。谢谢!

标签: arrays typescript protractor integration-testing undefined


【解决方案1】:

测试删除用户的选项:

最终,它是bad practice to make tests dependent on other tests

也就是说,两个或可能三个应该有效的选项:

A:在一个测试中遍历用户列表

describe(`Delete User`, async () => {
    describe(`Confirmation `, () => {
        it(`Log all users out who previously logged in`, async () => {
            list.forEach((item) => {
                console.log(item);
            });
        });
    });
});

由于list 数组是由上一个测试填充的,因此在下一个测试中插入依赖于它的代码将确保它具有可以使用的值。

B:一次测试登录和删除用户

describe(`Login and delete user `, async () => {
    tests.forEach(test => {
        it(` should login and delete user with ` + test.type, async () => {
            const myId = userPage.getUID().getText();
            // Select and delete myId here
        });
    });
});

您可以通过将整个用户流放入一个大型集成测试中来完全删除list 数组。

C:使用模拟数据(如果数据是随机的,可能不适用)

describe(`Delete User`, async () => {
    const list = ["QR417msytVrq", "V0fxayA3FOBD", "QnaiegiVoYhs"];
    describe(`Confirmation `, () => {
        list.forEach((item) => {
            it(
                ` should select and Delete the User having id as ` + item,
                async () => {}
            );
        });
    });
});

如果您提前知道要删除的值是什么,您可以手动添加它们。如果这些值是随机生成的,这将不起作用。

其他问题:

测试执行顺序

您使用的动态数组语法看起来不错,但是您的测试中似乎存在执行顺序问题。

在规范之外的 describe 函数中的代码(it 块)在规范内的任何代码之前执行。测试框架将遍历describe 块的树,执行它找到的任何代码,但只记录it 规范。完成此操作后,它会按顺序执行找到的it 规范。

当您尝试保存 list[0] 的值时,'Login User' 规范尚未执行。更具体地说:

describe(`Login User `, async () => {
    tests.forEach(test => {
        it(` should login user with ` + test.type, async () => {
            // This code is executed AFTER the code in the 'Delete User' 
            // block but BEFORE the 'Delete User' spec
            const myId = userPage.getUID().getText();
            list.push(myId);
        });
    });
});


describe(`Delete User`, async () => {
    // This code is executed before any specs are run
    let item = list[0];
    // List is [] when item is initialized
    // The following spec will therefore not work as item is undefined
    it(` should select and Delete the User having id as ` + item, async () => {
    });
});

可能的解决方案是将'Delete User' 规范的字符串更改为' should select and Delete first User' 之类的内容,并将规范之外的所有代码移到内部。

描述块不应返回承诺

您的代码示例包含返回 Promise 的 describe 块(特别是 'Login User''Delete User''Confirmation')。您应该删除函数声明前面的async。规格可以而且应该保持不变。例如:

describe(`Login User `, () => {

对象语法

示例开头的测试对象未使用 JS/TS 对象语法。每个键的值前应该跟一个冒号,而不是等号。你可能打算写:

const tests = [{
        type: 'admin',
        id: '',
        uname: 'foo',
        pass: 'bar'
    },
    {
        type: 'super',
        id: '',
        uname: 'foo1',
        pass: 'bar'
    },
    {
        type: 'normal',
        id: 'customId',
        uname: 'foo',
        pass: 'bar'
    }
];

来源:

【讨论】:

  • 感谢您的解决方案,但如果我必须遍历 list 并对每个列表项执行删除操作,应该怎么做。在那种情况下,我必须在如下所述的描述块中定义使用list.forEach,在这种情况下它甚至没有执行,还有其他替代方法来执行此操作吗? : { describe(Delete User, () => { list.forEach(item => { it( 应该选择并删除 id 为 ` + item, async () => { // 删除 id 为 item 的用户的代码。 }); }); }); }`
  • 而且,对于tests,是的,我在这里输入了它们,而没有过多注意语法。不过,这些在我的代码中已正确定义,但我仍在思考如果我必须遍历 list 并在列表中的每个项目上调用我的相同规范,该怎么办。
  • 更新了答案,为相关测试问题添加了一些可能的解决方案。
猜你喜欢
  • 2020-11-24
  • 1970-01-01
  • 2017-12-31
  • 2015-03-16
  • 2011-03-31
  • 2022-01-17
  • 2016-12-25
  • 2019-01-23
  • 2019-10-06
相关资源
最近更新 更多