Receber por email
← Voltar para o catálogo

shopify-testing

Test Shopify applications — app testing with Vitest and Playwright, theme testing with Theme Check, Function testing, webhook testing, extension testing, and CI/CD pipelines. Use when writing tests for Shopify projects.

34estrelas
Atualizado há 5 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add OrcaQubits/agentic-commerce-skills-plugins

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/shopify-testing/svg)](https://www.skillteca.com.br/skills/shopify-testing)

Skills relacionadas

Ver todas de DevOps e Infra →

Alerta por categoria

Receba novas skills de DevOps e Infra toda segunda

1 email curto, só com as skills novas de DevOps e Infra. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Shopify Testing

Before writing code

Fetch live docs:

  1. Web-search site:shopify.dev testing apps for app testing patterns
  2. Web-search site:shopify.dev theme check for theme linting
  3. Web-search site:shopify.dev shopify functions testing for function testing

App Testing

Unit Tests (Vitest)

The Remix template uses Vitest:

// tests/routes/app._index.test.tsx
import { describe, it, expect, vi } from 'vitest';
import { loader } from '~/routes/app._index';

describe('App index loader', () => {
  it('returns products', async () => {
    const context = {
      admin: {
        graphql: vi.fn().mockResolvedValue({
          json: () => ({ data: { products: { edges: [] } } }),
        }),
      },
    };

    const response = await loader({ context, request: new Request('http://test'), params: {} });
    const data = await response.json();
    expect(data.products).toBeDefined();
  });
});

Integration Tests (Playwright)

End-to-end testing with a development store:

import { test, expect } from '@playwright/test';

test('app loads in admin', async ({ page }) => {
  await page.goto('https://dev-store.myshopify.com/admin/apps/my-app');
  await expect(page.locator('[data-testid="app-page"]')).toBeVisible();
});

Mocking Shopify APIs

// Mock the admin GraphQL client
const mockAdmin = {
  graphql: vi.fn().mockImplementation((query) => {
    if (query.includes('products')) {
      return Promise.resolve({
        json: () => ({ data: { products: { edges: [] } } }),
      });
    }
  }),
};

Theme Testing

Theme Check

Static analysis for Liquid themes:

  • shopify theme check — run all checks
  • shopify theme check --auto-correct — fix auto-fixable issues
  • Categories: errors, suggestions, style
  • Checks: deprecated tags, missing templates, accessibility, performance

Manual Theme Testing

  • Test with shopify theme dev — live preview
  • Test all page types: home, product, collection, cart, checkout
  • Test responsive: mobile, tablet, desktop
  • Test accessibility: keyboard, screen reader, color contrast

Function Testing

Local Testing

shopify app function run --input input.json

Create test input JSON files:

{
  "cart": {
    "lines": [
      {
        "id": "gid://shopify/CartLine/1",
        "quantity": 2,
        "merchandise": {
          "__typename": "ProductVariant",
          "id": "gid://shopify/ProductVariant/123"
        }
      }
    ]
  }
}

Unit Tests for Functions

import { describe, it, expect } from 'vitest';
import { run } from '../src/run';

describe('discount function', () => {
  it('applies discount for VIP customers', () => {
    const input = {
      cart: { lines: [{ /* ... */ }] },
      discountNode: { metafield: { value: '{"percentage": 10}' } },
    };

    const result = run(input);
    expect(result.discounts).toHaveLength(1);
    expect(result.discounts[0].value.percentage.value).toBe('10.0');
  });

  it('returns empty discounts for non-VIP', () => {
    const input = { cart: { lines: [] }, discountNode: { metafield: null } };
    const result = run(input);
    expect(result.discounts).toHaveLength(0);
  });
});

Webhook Testing

Local Development

  • Use shopify app dev — sets up a tunnel and registers webhooks locally
  • Trigger events manually in development store admin
  • Check webhook delivery logs in Partner dashboard

Testing HMAC Verification

import { describe, it, expect } from 'vitest';
import crypto from 'crypto';

function createTestWebhook(body: object, secret: string) {
  const bodyStr = JSON.stringify(body);
  const hmac = crypto.createHmac('sha256', secret).update(bodyStr).digest('base64');
  return { body: bodyStr, hmac };
}

describe('webhook verification', () => {
  it('verifies valid HMAC', () => {
    const { body, hmac } = createTestWebhook({ order: { id: 1 } }, 'test-secret');
    expect(verifyWebhook(body, hmac, 'test-secret')).toBe(true);
  });

  it('rejects invalid HMAC', () => {
    expect(verifyWebhook('{}', 'invalid', 'test-secret')).toBe(false);
  });
});

CI/CD

GitHub Actions Example

name: Test Shopify App
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck
      - run: npm run test
      - run: shopify theme check (if theme)

Best Practices

  • Write unit tests for all Shopify Functions (they are pure functions — easy to test)
  • Mock Shopify API responses in app unit tests
  • Use Theme Check in CI to catch Liquid issues early
  • Test webhook HMAC verification with both valid and invalid signatures
  • Use development stores for integration testing — never test against production
  • Test checkout extensions with actual checkout flows in development stores
  • Include type checking (tsc --noEmit) in CI pipeline

Fetch the Shopify testing documentation for exact test patterns, Theme Check configuration, and CI/CD examples before implementing.

Compartilhar X LinkedIn