这就是问题,因为cypress集成测试在浏览器中运行,所以节点环境不可用,因此我无法在测试中的任何地方使用Pact对象。
尽管如此,我可以实现cypress task,并将所有与cypress相关的代码移至该任务,并通过其他任务进行所有通信。这样,流程就变得太复杂了,它需要在任务中支持Pact对象的生命周期,并复制所有消息。像这样:
cypress / plugins / index.js :
const {Pact} = require("@pact-foundation/pact")
module.exports = (on) => {
on("task", {
createPactServer() {
return new Pact({
consumer: "TodoApp",
provider: "TodoService",
port: 8501,
// log: path.resolve(process.cwd(), "logs", "pact.log"),
// dir: path.resolve(process.cwd(), "pacts"),
logLevel: "info",
})
}
})
}
cypress / integration / test.js :
describe("Login page", (): void => {
it("should log in", (): void => {
let a = cy.task('createPactServer', );
// do rest
// manage verify
// handle errors from verify
// shutdown pact server
// handle all other lifecycle events.
});
});
我想避免这种情况!
{木也随附route,可以模拟网络并存根响应。我想知道是否有任何方法可以将它们混合使用,所以我什至根本不会监听带有Pact服务器的端口。我没有发现任何以为我没有调查太久的方法。在我看来,还有一个pact-web只是没有http服务器的模拟部分,但是没有关于将其与API集成的文档。我还发现该协定使用了ruby文件,这可能使它无法在非节点环境中不使用http服务器。
我想知道是否无论如何尝试将它们耦合在一起,什么是首选方式。
答案 0 :(得分:1)
我刚刚创建了一个demonstration应用程序,将两者结合在一起。我发现经验是quite good。它的作用:
server
和相应的route
(这样很快)cy.wait
,因此保留了开发经验,就像您没有使用Pact一样。我打算将其提取到单独的cypress插件中。
下面是使用该插件的示例测试代码的样子:
示例
import { Matchers } from "@pact-foundation/pact-web";
const { like, eachLike } = Matchers;
let server;
const expectedProduct = {
id: "10",
type: "CREDIT_CARD",
name: "28 Degrees",
};
describe("Product page", () => {
describe("when products exist", () => {
before(() => {
cy.mockServer({
consumer: "example-cypress-consumer",
provider: "example-provider",
}).then(opts => {
server = opts
})
});
it("can navigate to an individual product", () => {
cy.addMockRoute({
server,
as: 'products',
state: "products exist",
uponReceiving: "a request to all products",
withRequest: {
method: "GET",
path: "/products",
},
willRespondWith: {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
body: eachLike(expectedProduct),
},
});
cy.addMockRoute({
server,
as: 'product',
state: "a product with ID 10 exists",
uponReceiving: "a request to get a product",
withRequest: {
method: "GET",
path: "/product/10",
},
willRespondWith: {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
body: like(expectedProduct),
},
});
// Navigate to products listing page
cy.visit("http://localhost:3000");
cy.wait("@products");
// Filter to the product we want
cy.get("#input-product-search").type("28 degrees");
// Navigate to individual product
cy.contains("See more!").click();
cy.wait("@product");
// ... Assert something about product page
});
});
});
最终思想
我仍然认为,在可能的情况下,在正确的层进行这种形式的测试是有意义的,在此您可以更直接地针对API客户端。但是这种方法可以解决许多问题(更广泛的受众,非常好的开发经验和翻新用例),并且如果使用得当,对于许多人来说都是一条不错的途径。
这是一段视频https://youtu.be/jTuuYMFJBBQ,其中显示:
/
,后者会调用产品列表API /products
/products/:id
的产品页面。测试失败,因为尚未在Cypress或Pact中配置交互功能product/:id
互动!答案 1 :(得分:-3)
为什么要把柏树和契约配对?我以前都曾经使用过,我认为最好避免这种依赖。
一方面,您可以将赛普拉斯用于E2E测试,因为赛普拉斯适用于在浏览器中运行的任何程序。这意味着您不需要直接引用服务,控制器等。 另一方面,您可以使用Pact JS(带有mocha)进行合同测试。如您所知,Pact遵循消费者驱动的合同方法。这意味着您必须从使用者创建pact文件,因为您必须针对控制器(或http call方法)进行单元测试,而不能使用cypress。