用途
本技能是一份 Shopify 应用测试指南,目标是帮助开发者验证应用是否正确处理 Shopify 的认证机制与 API 特性。可靠的测试对于确保应用在认证和 API 交互上的正确性至关重要。
主要能力
指南覆盖以下测试类型:
- 单元与集成测试(Vitest + Remix):在 Remix 环境中使用 Vitest 运行单元测试和集成测试。
- Mock Shopify 上下文:为
shopify.server.ts中的authenticate对象创建 Mock,从而在不调用真实 Shopify API 的情况下测试 loader 和 action。 - 测试 Loader 与 Action:使用 Remix 的
createRemixStub或直接调用 loader/action 来测试后端逻辑。 - 端到端(E2E)测试(Playwright):处理 OAuth 流程,或通过 session token 绕过认证。
- 测试 Webhook:在本地触发 Webhook,或通过单元测试验证 HMAC。
使用方式
1. 单元与集成测试环境搭建
安装依赖:
npm install -D vitest @testing-library/react @testing-library/jest-dom jsdom
2. Mock shopify.server.ts
为 authenticate 对象创建 Mock 是测试 loader 和 action 的关键,可避免调用真实 Shopify API。
// test/mocks/shopify.ts
import { vi } from 'vitest';
export const mockShopify = {
authenticate: {
admin: vi.fn(),
public: vi.fn(),
webhook: vi.fn(),
},
};
// Usage in test file:
vi.mock('../app/shopify.server', () => mockShopify);
test('loader returns data for authenticated shop', async () => {
mockShopify.authenticate.admin.mockResolvedValue({
currentShop: 'test-shop.myshopify.com',
session: { shop: 'test-shop.myshopify.com', accessToken: 'fake_token' },
admin: {
graphql: vi.fn().mockResolvedValue({ /* mock response */ })
}
});
const response = await loader({ request: new Request('http://localhost/') });
// Assertions...
});
3. 测试 Loader 与 Action
直接调用函数(推荐用于逻辑测试):可以导入 loader 或 action,并用 Mock Request 直接调用。
import { loader } from '../app/routes/app.dashboard';
test('dashboard loader returns stats', async () => {
// Setup mocks...
const response = await loader({
request: new Request('http://localhost/app/dashboard'),
params: {}
});
const data = await response.json();
expect(data.stats).toBeDefined();
});
4. 端到端(E2E)测试(Playwright)
对于 E2E 测试,需要处理 OAuth 流程,或使用 session token 绕过它。绕过认证(Session Token)是测试嵌入式应用最稳定的方式:生成有效的 session token(或 Mock 校验),从而无需自动化登录界面交互(登录界面常触发验证码)。
基础 Playwright 测试示例:
import { test, expect } from '@playwright/test';
test('load dashboard', async ({ page }) => {
await page.goto('http://localhost:3000/app');
// Expect to see the Polaris Page title
await expect(page.locator('.Polaris-Page-Header__Title')).toHaveText('Dashboard');
});
5. 测试 Webhook
在本地测试 Webhook 有两种方式:
- 通过 Shopify CLI 触发:
shopify app webhook trigger --topic ORDERS_CREATE - 单元测试:导入 webhook action,并传入带有正确 HMAC 头的 Mock Request。
import { action } from '../app/routes/webhooks';
import crypto from 'crypto';
test('webhook verifies hmac', async () => {
const payload = JSON.stringify({ id: 123 });
const hmac = crypto.createHmac('sha256', 'FULL_SECRET').update(payload).digest('base64');
const request = new Request('http://localhost/webhooks', {
method: 'POST',
body: payload,
headers: { 'X-Shopify-Hmac-Sha256': hmac }
});
// Mock authenticate.webhook to succeed
// ...
const response = await action({ request });
expect(response.status).toBe(200);
});
适用场景
- 为 Shopify 应用编写单元测试与集成测试。
- 需要在测试中隔离 Shopify 认证与 API 调用。
- 对嵌入式 Shopify 应用进行 E2E 测试。
- 验证 Webhook 的 HMAC 校验逻辑。
限制
资料未提供关于支持的具体 Shopify API 版本、Remix 版本、Playwright 配置细节、CI 集成方式以及除上述示例外的其他测试工具或框架的信息。