Testing 如何跨多个套件共享响应数据?

Testing 如何跨多个套件共享响应数据?,testing,cypress,Testing,Cypress,假设我们有以下套件: describe('Devices', () => { describe('Master Data Set-Up', () => { it('should create the device if necessary', () => { cy.createDevice() its('body.id') .as('deviceId');

假设我们有以下套件:

describe('Devices', () => {
    describe('Master Data Set-Up', () => {
        it('should create the device if necessary', () => {
            cy.createDevice()
                its('body.id')
                .as('deviceId');
        });
    });
    describe('Test Suite 1', () => {
        it('should allow to send data to device', () => {
            cy.get('@deviceId').then((deviceId) => {
                cy.sendData(deviceId, 'Some Data');
            });
        });
    });
});
因此,我们有一个创建主数据的设置套件。这是一个简化的版本,实际上它包含了几个it规范,我希望保持这样,因为最好在Cypress输出中读取

然后,实际的测试套件希望使用以前创建的数据。在这种情况下,服务器生成的id应该用于另一个REST调用

这是假设
cy.createDevice
cy.sendData
是内部使用
cy.request
的自定义命令

运行该命令时,
cy.get('@deviceId')
会失败,因为别名不会在描述块之间共享。我尝试使用
let deviceId
,但它没有定义,因为在处理测试规范时它还不可用


什么是正确的方法呢?

我相信这将是更好的解决方案,因为cypress是异步的,所以最好将其写入文件并读取

describe('Devices', () => {
describe('Master Data Set-Up', () => {
    it('should create the device if necessary', () => {
        cy.createDevice()
        ......
        cy.writeFile('deviceId.txt', body.id)
            
    });
});
describe('Test Suite 1', () => {
    it('should allow to send data to device', () => {
        cy.readFile('deviceId.txt').then((device_id) => {
            cy.sendData(device_id, 'Some Data');
        })
            
        });
    });
});

投票支持@ArekKhatry的想法,但为了安全起见,我会在
before()
中获得id。如果您曾经并行运行测试,那么从一个测试中获取数据以在另一个测试中使用将是不可靠的

请注意,在
before()
中运行
cy.createDevice().its('body.id')
仍然可以提供与在
it()
中运行相同的测试覆盖率,即它测试请求是否成功以及返回值是否具有id

文件应写入
cypress/fixtures
,否则将写入项目根目录,导致文件结构不整洁

此外,id作为数字从
cy.request()
返回,但必须字符串化才能写入文本文件

这是我的变体

description('Devices',()=>{
之前(()=>{
cy.createDevice()
.its('body.id')
。然后(id=>{
cy.writeFile('cypress/fixtures/deviceId.txt',id.toString());
cy.log(`Created device:${id}`);
});
});
描述('测试套件1',()=>{
它('应该允许向设备发送数据',()=>{
cy.fixture('deviceId')//这里可以使用更简单的cy.fixture
.then(device_id=>{//在此处作为字符串返回
const id=parseInt(设备_id);//可能需要解析到数字?
cy.sendData(id,“某些数据”);
})
});
});
});

好的,首先感谢阿洛伊修斯和阿雷克的回答。但我有一种直觉,那就是一定有更简单的方法可以做到这一点,那就是向文件中写入Id

如前所述,我第一次尝试使用全局变量时遇到了问题:

我试图使用let deviceId,但它还没有定义,因为它还没有定义 处理测试规格时可用

我真的很想理解,为什么这不起作用,并进行了一些控制台调试

我添加了一个控制台日志:

description('Devices',()=>{
log('加载测试套件…')
(...)
});
在运行测试时,我看到了两次日志输出,一次是在存储设备id的第一个descripe块之后,另一次是在写入主数据之后

事实上,我发现这个问题是由以下已知的柏树问题引起的:

设置baseUrl后,它实际上可以工作:


描述('设备',()=>{
让deviceId;
之前(()=>{
Cypress.config('baseUrl',Cypress.env('system\u url'))
cy.visit('/');
})
描述('主数据设置',()=>{
它('必要时应创建设备',()=>{
cy.createDevice()
.its('body.id')
。然后((id)=>{
deviceId=id;
});
});
});
描述('测试套件1',()=>{
它('应该允许向设备发送数据',()=>{
cy.sendData(deviceId,“某些数据”);
});
});
});

Hi。除了作为反模式的全局变量之外,这篇文章可能会有所帮助:可以尝试使用writeFile和readFile,如果测试并行运行,这可能会失败。最好在
before()中获取id
。另外,要保存的模式是
cy.createDevice().its('body.id')。然后(id=>cy.writeFile('deviceId.txt',id))