Modern QA2026When Hybrid Is the Right Choice — tiles
Log inJoin
84 / 87 · 02 AI-Augmented Test Design · Write vs Generate: The Decision Matrix← prev⊞ allnext →☰ Read as one page

12.4When Hybrid Is the Right Choice

The hybrid approach combines human-written test structure with AI-generated permutations. This is ideal for complex scenarios.

Example: Payment Flow Testing

# HUMAN-WRITTEN: the test structure and key assertions
class TestPaymentFlow:
    """Integration tests for the full payment flow."""

    def _create_and_process_order(self, client, payment_method, amount):
        """Helper: create order, process payment, return result."""
        order = client.post("/api/orders", json={
            "items": [{"product_id": "prod-1", "quantity": 1}],
            "payment_method": payment_method,
            "amount": amount,
        })
        assert order.status_code == 201
        order_id = order.json()["id"]

        payment = client.post(f"/api/orders/{order_id}/pay")
        return payment

    def test_successful_credit_card_payment(self, client, mock_stripe):
        """Verify complete happy path for credit card payment."""
        mock_stripe.charge.return_value = {"status": "succeeded", "id": "ch_123"}

        result = self._create_and_process_order(client, "credit_card", 99.99)

        assert result.status_code == 200
        assert result.json()["payment_status"] == "completed"
        assert result.json()["stripe_charge_id"] == "ch_123"
        mock_stripe.charge.assert_called_once()

    # AI-GENERATED: permutations of failure modes
    # (generated with: "Given the test structure above, generate tests for
    #  every Stripe error: card_declined, expired_card, incorrect_cvc,
    #  processing_error, rate_limit. Follow the same pattern.")

    @pytest.mark.parametrize("stripe_error,expected_status,expected_message", [
        ("card_declined", "failed", "Your card was declined"),
        ("expired_card", "failed", "Your card has expired"),
        ("incorrect_cvc", "failed", "Incorrect CVC"),
        ("processing_error", "pending", "Payment is being processed"),
        ("rate_limit", "pending", "Please try again in a moment"),
    ])
    def test_stripe_error_handling(self, client, mock_stripe,
                                    stripe_error, expected_status, expected_message):
        mock_stripe.charge.side_effect = StripeError(stripe_error)

        result = self._create_and_process_order(client, "credit_card", 99.99)

        assert result.json()["payment_status"] == expected_status
        assert expected_message in result.json()["error_message"]

The human writes the complex test infrastructure (helpers, mocking setup, key assertions). The AI generates the systematic permutations (every error code, every payment method, every amount range).