【问题标题】:How to change property of a record in db with cypress.io如何使用 cypress.io 更改 db 中记录的属性
【发布时间】:2023-03-26 17:35:02
【问题描述】:

我是 cypress 的新手,我想知道如何进行以下检查: 我有一个案例: 我在数据库中有一个产品,它可以有状态:InStock 和 OutOfStock 和 Discontinued。如果产品处于“InStock”状态,我应该能够将其发送给客户,如果处于“OutOfStock”/“Discontinued”状态,我应该无法发送给客户。 通过 API 调用,我可以将产品发送给客户。如果产品处于“InStock”状态,则 API 响应为 200,否则响应为 statusCode 400。 所以我的问题是:如何为每个测试更改数据库中产品的状态,以便我可以检查这 3 个状态中的每一个(如果 API 返回正确的响应)?我知道如何检查 API 响应本身,但我不清楚如何在每次测试之前更改数据库中产品的状态。

【问题讨论】:

    标签: node.js database cypress


    【解决方案1】:

    与@Maccurt 不同,我实际上按照您建议的方式进行(更改数据库),因此您可以正确测试 e2e 流程。

    您可以使用cy.task 与可以直接写入数据库的 Cypress Runner 的节点进程对话,而不是设置写入数据库的测试路由。它看起来像这样:

    在本例中使用 postgres (node-postgres)。

    your-test.spec.js

    describe("test", () => {
        it("test", () => {
            cy.task("query", {
                sql: `
                    UPDATE product
                    SET status = $1
                    WHERE id = $2
                `,
                values: [ "InStock", 40 ]
            });
    
            // your cy assertions here
        });
    });
    

    cypress/plugins/index.js

    const pg = require("pg");
    const pool = /* initialize your database connection */;
    
    module.exports = (on) => {
        on("task", {
            query ({ sql, values }) {                
                return pool.query(sql, values);
            }
        });
    });
    

    【讨论】:

    • 我觉得这一切都很有趣。我对我们在这里测试的内容感到困惑。如果我们正在测试 API 和数据库,那么我会说这个测试不应该是赛普拉斯测试。让我更加努力地看看我们在这里想要完成什么。
    • Cypress docs 自己注意到 e2e 是有价值的。拥有单独的 DB/端点测试(或 stubbing cypress 测试)很有用(我们也在这样做),但并不能 100% 保证您的网络应用程序会按预期工作。
    • 您的建议@Dwelle 正是我想要的。就我而言,我想连接到 mysql db,但是当我按照您的想法进行操作时,我遇到了以下错误:TypeError: Converting circular structure to JSON
    • 不确定你在哪里得到错误,但可能来自query 任务,它试图对你的数据库查询的返回值进行 JSON 字符串化。如果是这样,你应该做类似return pool.query(sql, values).then( resp => resp.rows ) 或任何适用于你的事情。如果不是这样,那么其他候选对象是当您调用 cy.task('query', data) 时 - 确保您传递的 data 是一个没有循环引用自身的普通对象。
    • 这里是 index.js:const pool = mysql.createPool(config) module.exports = ( on ) => { on('task', { querydb (statement) { return pool.query(statement) } }) } 和测试本身:describe("test", () => { it("test", () => { cy.task('querydb', 'UPDATE table SET status = 0 WHERE product = 5035;'); }); }); 仍然出现错误:TypeError: Converting circular structure to JSON 也尝试使用 return pool.query(statement).then( resp => resp.rows ),但后来我得到:TypeError: pool.query(...).then is not a function
    【解决方案2】:

    您想模拟您的 api 调用,以便它响应您想要的内容。赛普拉斯称之为存根。这将允许您拦截您的 Rest 调用并将其替换为您想要的。您也可以调用 API 来重置数据库,但我不建议这样做。

    https://docs.cypress.io/guides/guides/network-requests.html#Requests

    cy.server()           // enable response stubbing
    cy.route({
      method: 'GET',      // Route all GET requests
      url: '/users/*',    // that have a URL that matches '/users/*'
      response: []        // and force the response to be: []
    })
    

    【讨论】:

    • 感谢@Maccurt 的回复,但我想检查的是,当数据库中有严格的情况时,api 响应是否正确。这与请求或响应无关(我无法控制产品的状态)。基本上在请求中我给出了产品的 id 并请求发送它,然后在响应中我期望 400 - 如果产品不处于正确的状态,或者 200 如果一切都很好并且它被发送了。
    • 如果你想测试 API 和 DB,你能把测试放在那个层吗?
    • 我只想测试 API。问题是,只有当我知道数据库中产品的状态时,我才能断言 api 响应符合预期。我还必须针对不同的产品状态检查 api 响应,我能想到的最简单的方法是自己在数据库中使用更新查询更改这些状态​​。
    猜你喜欢
    • 2017-10-31
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    相关资源
    最近更新 更多