使用 cypress.io 模拟 s-s-r 反应应用程序 e2e 测试的服务器
Posted
技术标签:
【中文标题】使用 cypress.io 模拟 s-s-r 反应应用程序 e2e 测试的服务器【英文标题】:mocking server for s-s-r react app e2e tests with cypress.io 【发布时间】:2018-05-17 19:51:35 【问题描述】:我正在构建一个带有服务器端渲染 (s-s-r) 的单页 Web 应用程序 (SPA)。
我们有一个节点后端 API,它在 s-s-r 期间从节点服务器调用,在初始渲染后从浏览器调用。
我想编写配置 API 响应的 e2e 测试(例如使用 nock
)并同时使用浏览器调用和 s-s-r 服务器调用。一些伪代码:
it('loads some page (s-s-r mode)', () =>
mockAPI.response('/some-path', text: "some text"); // here i configure the mock server response
browser.load('/some-other-page'); // hit server for s-s-r response
expect(myPage).toContain('some text');
)
it('loads some other page (SPA mode)', () =>
mockAPI.response('/some-path', text: "some other text"); // here i configure another response for the same call
browser.click('#some-link'); // loads another page client side only : no s-s-r here
expect(myPage).toContain('some other text');
)
目前 Cypress 允许我在浏览器上模拟 fetch,但不能在服务器上模拟 fetch。
有什么可以实现的吗? 最好使用节点库。
【问题讨论】:
【参考方案1】:我们使用了一个特别丑陋的解决方案,它破坏了 cypress 的速度,但我们需要它来模拟/伪造套接字调用。
您可以创建一个真正简单的快速服务器,在运行测试之前启动。这个“真正的假服务器”将能够响应您的需求。 以下是我们的规格:
在/
上发布 method
、path
和 data
在正文参数中以设置路线
/path
上的 GET/POST/PUT/DELETE 响应 data
DELETE on /
清除所有路由
让我们考虑一下您的“真正的假服务器”在 0.0.0.0:3000 上运行;你会做的:
beforeEach()
cy.request('DELETE', 'http://0.0.0.0:3000/');
it('loads some page (s-s-r mode)', () =>
cy.request('POST', 'http://0.0.0.0:3000/',
method: 'GET',
path: '/some-path',
data: text: "some other text"
) // here i tell my 'real fake server' to
// respond text: "some other text" when it receives GET request on /some-path
browser.load('/some-other-page'); // hit server for s-s-r response
expect(myPage).toContain('some text');
)
it('loads some other page (SPA mode)', () =>
cy.request('POST', 'http://0.0.0.0:3000/',
method: 'GET',
path: '/some-path',
data: text: "some other text"
); // here i configure another response for the same call
browser.click('#some-link'); // loads another page client side only : no s-s-r here
expect(myPage).toContain('some other text');
)
重要:resquests 需要在 localhost 中。你将无法存根外部的东西。 (因此,当你测试你的应用程序时,为了请求 localhost:xxxx 而不是 google.com,创建一个 env var)
除了这个 cy.request 之外,您将无法控制“真正的假服务器”,因为您的测试脚本在浏览器中运行(如果我错了,请纠正我)并且浏览器无法运行快速服务器.
【讨论】:
这就是我们最终所做的。我正在寻找现有的模拟服务器(最好在节点中)。我终于找到了:看看我的答案【参考方案2】:MockTTP 可以做到这一点。文档摘录:
const superagent = require("superagent");
const mockServer = require("mockttp").getLocal();
describe("Mockttp", () =>
// Start your server
beforeEach(() => mockServer.start(8080));
afterEach(() => mockServer.stop());
it("lets you mock requests, and assert on the results", () =>
// Mock your endpoints
mockServer.get("/mocked-path").thenReply(200, "A mocked response")
.then(() =>
// Make a request
return superagent.get("http://localhost:8080/mocked-path");
).then(() =>
// Assert on the results
expect(response.text).to.equal("A mocked response");
);
);
);
【讨论】:
这是一个展示 Cypress + Mockttp 集成的示例 repo:github.com/mvasin/cypress-mockttp 它能够模拟本地 API 路由吗?因为它们与您的 Next 应用在同一个端口上运行? 我收到“网络请求失败,因为这个错误发生在每个钩子之前,我们跳过了所有剩余的测试。”我按照这些例子来做这封信。 MockServer 是一个类似的工具:mock-server.com 你能用mock service worker添加一个例子吗?以上是关于使用 cypress.io 模拟 s-s-r 反应应用程序 e2e 测试的服务器的主要内容,如果未能解决你的问题,请参考以下文章
使用 firebase-functions 部署基于反应的 s-s-r 应用程序时出错