smplx.
Shopify Architecture

Testing and QA for Shopify Projects: Checklist [2026]

Claudio Gerlich··12 min

In our Shopify Architecture Guide, we cover the fundamentals. Today: The last 10% of the project that often causes 90% of the problems.

At smplx., we've learned: An "almost finished" shop is not the same as a "launch-ready" shop. Testing and QA are not extras — they are architecture.

Why QA Is Critical

The numbers:

  • 0.1% of visitors make a purchase
  • Every error in checkout = direct revenue loss
  • Mobile is fragile (browser tests don't catch that)
  • Payment errors are existentially threatening

Reality: You can't test everything manually. You need a strategy.

What You Need to Test

1. Checkout Flow (Highest Priority)

Critical Paths:

  • Add product -> Cart
  • Change quantities
  • Enter coupon (valid, invalid, expired)
  • Start checkout
  • Select shipping method
  • Enter payment
  • Show order confirmation
  • Receive email

Scenarios:

  • Normal credit card checkout
  • Guest checkout
  • Logged-in customer
  • Express payment (Google Pay, Apple Pay)
  • Multi-currency (if relevant)
  • From different countries

Test Payments:

Stripe Test Cards:
- 4242 4242 4242 4242 (Success)
- 4000 0000 0000 0002 (Decline)
- 4000 0025 0000 3155 (Requires 3D Secure)

Klarna Test:
- 4111 1111 1111 1111 (Success - Invoice)

2. Responsive & Browser Testing

Test devices:

  • Desktop (1920x1080, 1440x900, 1024x768)
  • Tablet (iPad, Samsung Tab)
  • Mobile (iPhone 12, iPhone SE, Samsung Galaxy)
  • Old Mobile (iPhone 8)

Test browsers:

  • Chrome (latest version)
  • Safari (Mac + iOS)
  • Firefox (latest)
  • Edge
  • Mobile Safari (iOS)
  • Chrome Mobile (Android)

Tools:

BrowserStack: https://www.browserstack.com
- Real devices in the cloud
- Automated screenshot tests

3. Performance Testing (Web Vitals)

Test with Lighthouse:

# Terminal
lighthouse https://shop.example.com --view

Targets:

  • LCP < 2.5s
  • INP < 100ms
  • CLS < 0.1
  • Overall Score > 85

Measure with Web Vitals:

// In theme or headless app
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';

function sendMetrics(metric) {
  // Send to analytics
  fetch('/api/metrics', {
    method: 'POST',
    body: JSON.stringify(metric)
  });
}

getCLS(sendMetrics);
getFID(sendMetrics);
getFCP(sendMetrics);
getLCP(sendMetrics);
getTTFB(sendMetrics);

4. SEO Testing

With axe DevTools (free):

# Chrome browser extension
# Checks: Accessibility + Basic SEO

Manual checks:

  • H1 on every page (exactly one)
  • Meta descriptions (all pages)
  • Open Graph tags (social sharing)
  • Structured data (JSON-LD for products)
  • Sitemap.xml exists
  • robots.txt not too restrictive

Example: Product Structured Data

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "{{ product.title }}",
  "description": "{{ product.description }}",
  "image": "{{ product.featured_image | image_url: width: 800 }}",
  "brand": {
    "@type": "Brand",
    "name": "{{ shop.name }}"
  },
  "offers": {
    "@type": "Offer",
    "price": "{{ product.selected_or_first_available_variant.price | divided_by: 100 }}",
    "priceCurrency": "{{ shop.currency }}",
    "availability": "https://schema.org/{% if product.selected_or_first_available_variant.available %}InStock{% else %}OutOfStock{% endif %}"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "{{ product.metafields.reviews.rating.value | default: 5 }}",
    "reviewCount": "{{ product.metafields.reviews.count.value | default: 0 }}"
  }
}
</script>

5. Accessibility Testing

Tools:

  • axe DevTools (Chrome Extension)
  • WAVE (WebAIM)
  • Lighthouse Accessibility Audit

Critical Checks:

  • All images have alt text
  • Color contrast is sufficient
  • Keyboard navigation works (tab through links)
  • Form labels are correct (not just placeholders)
  • ARIA labels where needed

Example: Accessible Form

<!-- WRONG -->
<input type="email" placeholder="Email">

<!-- RIGHT -->
<label for="email">Email</label>
<input type="email" id="email" name="email" required>

6. Payment & Tax Compliance

Test:

  • Shipping calculations (correct by country)
  • Tax calculations (sales tax, VAT)
  • Currency conversions (if multi-currency)
  • Payment methods available (by country)
  • Address validation works

Example: Shipping Calculation

// Shopify GraphQL
query CalculateShipping {
  cart(cartId: "...") {
    estimatedCost {
      shippingEstimate {
        amount
      }
      totalTaxEstimate {
        amount
      }
      subtotalAmount {
        amount
      }
      totalAmount {
        amount
      }
    }
  }
}

7. Mobile Payment Testing

Important: Apple Pay and Google Pay only work on real devices!

Setup:

  • Apple Pay on test device
  • Google Pay on Android

Test with real devices:

Stripe Test Card for Apple Pay:
- Card Number: 4242 4242 4242 4242
- Exp: 12/26
- CVC: 123

Testing Tools and Setups

Automated Testing: End-to-End

With Playwright (recommended):

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

test('Complete Checkout Flow', async ({ page }) => {
  // 1. Go to shop
  await page.goto('https://shop.example.com');

  // 2. Click product
  await page.click('[data-test="product-card"]');
  expect(page).toHaveURL(/\/products\//);

  // 3. Add to cart
  await page.click('button:has-text("Add to cart")');
  await page.waitForURL('**/cart');

  // 4. Start checkout
  await page.click('button:has-text("Checkout")');
  await page.waitForURL('**/checkout');

  // 5. Enter email
  await page.fill('input[type="email"]', 'test@example.com');

  // 6. Shipping address
  await page.fill('input[placeholder="First name"]', 'Test');
  await page.fill('input[placeholder="Last name"]', 'User');
  await page.fill('input[placeholder="Address"]', '123 Main St');

  // 7. Select shipping method
  await page.click('text=Standard Shipping');

  // 8. Payment
  // Stripe iFrame handling is complex
  // But Shopify managed checkout makes it easier

  // 9. Order confirmation
  expect(page).toContain('Order #');
});

test('Coupon is applied', async ({ page }) => {
  await page.goto('https://shop.example.com/cart');
  await page.fill('input[placeholder="Discount code"]', 'SAVE10');
  await page.click('button:has-text("Apply")');

  // Price should be updated
  await page.waitForSelector('text=Subtotal');
  const originalPrice = await page.locator('text=Subtotal').evaluate(el => el.textContent);
  expect(originalPrice).toContain('$');
});

Run:

npx playwright test
# Or with UI
npx playwright test --ui

Performance Testing: Lighthouse CI

// lighthouserc.json
{
  "ci": {
    "collect": {
      "url": [
        "https://shop.example.com",
        "https://shop.example.com/products",
        "https://shop.example.com/collections"
      ],
      "numberOfRuns": 3
    },
    "assert": {
      "preset": "lighthouse:recommended",
      "assertions": {
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
        "first-input-delay": ["error", { "maxNumericValue": 100 }]
      }
    }
  }
}
lhci autorun

Pre-Launch Checklist

72 Hours Before Launch

Functionality:

  • All products visible + images load
  • Variants work (all options)
  • Inventory correct (overselling not possible)
  • All payment methods active
  • All shipping methods tested
  • All coupons/discounts tested
  • Email confirmations work

Performance:

  • Lighthouse Score > 85
  • LCP < 2.5s (mobile)
  • No broken images
  • No 404s

SEO:

  • Sitemap.xml submitted to Google
  • Meta descriptions all pages
  • Robots.txt not too restrictive
  • Structured data ok (rich snippets)

Security:

  • HTTPS everywhere
  • CSP headers set
  • XSS protection
  • CSRF protection (Shopify default)

Legal:

  • Privacy policy current
  • Terms & conditions ok
  • Return policy clear
  • Legal notice (GDPR)

24 Hours Before Launch

  • Database backup
  • Monitoring setup (analytics, error tracking)
  • Incident response plan (who does what if there's a problem)
  • Support system online (email, chat)
  • Marketing campaign ready (don't start on launch day)

After Launch (24-48h Monitoring)

  • Error rates monitored
  • Payment success rate > 95%
  • Page load times ok
  • Customer support tickets scanned (reveals patterns)
  • Conversion rate normal (no anomalies)

Post-Launch Monitoring

Real User Monitoring (RUM)

// In theme or app
// Send metrics to monitoring service

window.addEventListener('error', (event) => {
  fetch('/api/errors', {
    method: 'POST',
    body: JSON.stringify({
      message: event.message,
      stack: event.error?.stack,
      url: window.location.href,
      timestamp: new Date()
    })
  });
});

// Unhandled Promise Rejections
window.addEventListener('unhandledrejection', (event) => {
  fetch('/api/errors', {
    method: 'POST',
    body: JSON.stringify({
      message: 'Unhandled Promise Rejection',
      error: event.reason,
      timestamp: new Date()
    })
  });
});

Key Metrics to Watch

Dashboard with:

  • Conversion Rate (Visits -> Purchases)
  • Cart Abandonment Rate
  • Average Order Value
  • Payment Success Rate
  • Page Load Time (Real Users)
  • Error Rate (Frontend + Backend)
  • Customer Support Tickets

Tools:

  • Google Analytics 4 (free)
  • Shopify Admin Reports
  • Sentry (Error Tracking)
  • Databox (KPI Dashboard)

Incident Response

When a problem occurs:

1. Detect (Monitoring alert)
   └─ Severity: Critical/High/Medium/Low

2. Acknowledge (Team is notified)
   └─ On-call person: [Name]

3. Assess
   └─ Impact: Revenue loss? UX broken? API down?

4. Mitigate (Fast!)
   └─ Theme rollback?
   └─ Disable app?
   └─ Maintenance mode?

5. Fix (Root Cause)
   └─ Code debug
   └─ Deploy fix

6. Monitor (24h after fix)
   └─ Error rate still ok?
   └─ Performance normal?

7. Postmortem (next day)
   └─ Why did it happen?
   └─ How do we prevent it in the future?

Testing for Different Shopify Architectures

Theme-Based Shop (Liquid)

Focus:

  • Theme performance
  • Liquid template errors
  • CSS/JS conflicts
  • Browser compatibility

Tools:

  • Lighthouse
  • BrowserStack
  • Chrome DevTools

Headless Shop (Next.js/Remix)

Focus:

  • API error handling
  • Storefront API rate limits
  • SSR/SSG performance
  • Data freshness

Tools:

  • Jest (unit tests)
  • Playwright (E2E tests)
  • K6 (load testing)
// Jest Example
describe('Product Page', () => {
  it('should fetch product data from Storefront API', async () => {
    const response = await fetchProduct('123');
    expect(response).toHaveProperty('id');
    expect(response).toHaveProperty('title');
  });

  it('should handle API errors gracefully', async () => {
    const response = await fetchProduct('invalid');
    expect(response).toBeNull();
  });
});

Multi-App Ecosystem

Focus:

  • App communication (when apps interact)
  • Webhook handling
  • API rate limits
  • Data consistency

Tools:

  • API Monitoring (Postman, Insomnia)
  • Webhook Testing (webhook.cool)
  • Load Testing (Apache JMeter)

QA Checklist (Copyable)

# Pre-Launch QA Checklist

## Functional Testing
- [ ] Homepage loads
- [ ] Product pages load with images
- [ ] Variants work (all options)
- [ ] Add to cart works
- [ ] Cart shows correct totals
- [ ] Checkout flow complete
- [ ] Payment processes successfully
- [ ] Order confirmation email sent
- [ ] Customer account created (if applicable)

## Responsive Design
- [ ] Mobile (320px) looks ok
- [ ] Tablet (768px) looks ok
- [ ] Desktop (1920px) looks ok
- [ ] Touch targets are at least 44x44px
- [ ] No horizontal scroll
- [ ] Images scale properly

## Performance
- [ ] Lighthouse Score > 85
- [ ] LCP < 2.5s
- [ ] FID < 100ms
- [ ] CLS < 0.1
- [ ] Page size < 5MB

## SEO
- [ ] Meta descriptions set
- [ ] H1 tags correct
- [ ] Open Graph tags
- [ ] Structured data valid
- [ ] Sitemap submitted

## Security
- [ ] HTTPS everywhere
- [ ] No console errors
- [ ] Payment data secure
- [ ] PII protected

## Browsers
- [ ] Chrome (latest)
- [ ] Safari (Mac + iOS)
- [ ] Firefox (latest)
- [ ] Edge (latest)

## Payment
- [ ] Test card works
- [ ] Invalid card rejected
- [ ] Tax calculated
- [ ] Shipping calculated
- [ ] Coupons work

About the Author

Claudio Gerlich is Technical Architect at smplx. and has specialized in Shopify since 2020. With dozens of launches, we've learned: 90% of launch problems are preventable with a good QA strategy.

QA is not "boring testing." It's risk avoidance. It's revenue protection.

smplx. is a Shopify Technical Partner (since 2020) based in Muensterland, NRW.