- Tom Hacohen
Testing event driven architectures is a pain, and webhooks are no exception. When testing webhooks you need to have your test suite be able to receive and verify webhooks are what you expect. This often means that your test suite would need to be able to receive webhooks from 3rd parties over the internet. While this is doable, and there are some utilities that help with that (including our own Svix Play), we thought we could make things even easier. That's why we are now introducing the Svix Play API.
We have been using the Svix Play API in our internal test suite for over a year and have had customers testing it for the last few months, so we figured it's finally ready for public release! The Play API makes it extremely easy to test webhooks as part of your test suite. We made it our goal to make webhooks easy and reliable for everyone, whether you are a Svix customer or not, and we hope this will lead to easier and better testing of webhooks.
When talking about testing webhooks, it's important to differentiate between two scenarios. The first is testing your own webhooks, so webhooks that you send as part of your service, and the tests should cover that the right events are sent at the right times (and with the right data). The second is more of an integration test, and the idea there is to verify that a specific action with a third party causes the expected activity on your end (triggered by a webhook).
We will cover below some common ways of testing webhooks, and while most of them work for both, some of them only make sense for one or the other.
This is the easiest and most straightforward way of dealing with webhooks testing; not doing it. Because testing webhooks is a pain, many people just don't bother with testing their integrations. This is not recommended, but still worth mentioning as it's quite common!
Mocking webhooks essentially means triggering the webhook handler without actually receiving a webhook. So if for example you have a function called
handle_incoming_webhook(), you'll call it directly from your test suite with a known payload, signature and timestamp. This works especially well with tests that also mock API calls to external services.
So for example, if you're testing a Stripe integration, your test may look something like this:
def test_payment(): # ... snip ... fake_stripe_payment(customer) # Calling our webhook handler handle_stripe_webhook("invoice.payment_failed", invoice_failed_payload, headers) assert get_customer().status == PaymentFailed
Svix makes it very easy to mock webhooks by providing libraries for many languages that also support signing payloads.
Forwarding requests to the test instance
Another common option is using a tool like ngrok or Svix Play's listen command to forward all webhooks to the local test runner. This is most often used as a way of doing integration tests to ensure that the full integration path works when dealing with an external service. The may issues with this however is that it's more annoying to setup, and it makes the tests much less reliable as it depends on network conditions, and multiple tests can conflict.
Testing with the new Svix Play API
The new Svix API works best in conjunction with mocking, or potentially as a simple alternative to forwarding requests. It's great for testing webhooks you receive from third parties, but even better for testing your own webhook system.
When testing external webhooks, the Svix Play API essentially gives you a persistent URL that you can use with your webhooks sender (e.g. https://play.svix.com/in/e_94XdF-OwN3EaTKty4izJDWRAH3V/) which you can configure the webhooks provider to send webhooks to. All the webhooks will then be sent to Play, and you will be able to use the API to poll it and check for new messages and then act on them accordingly. This makes things much nicer when testings in environments where proxying isn't easy or possible.
When testing webhooks that you send, it can do much more. For example, you can make it return specific status codes (e.g. 429 or 503), as well as echo the full request body back to the sender. These make it very easy to verify your webhook implementation is sending exactly what you expect it to send, and to ensure that it correctly handles various error codes. If you use the Svix libraries for signing payloads, you can also have it automatically verify webhooks are signed correctly for even more robust testing.
We use the Play API internally in our test suite, canary tests, and ongoing monitoring to ensure that the Svix service continues to run smoothly with no interruption, and we are releasing it to the public today in the hopes that it will help more webhook providers send more reliable webhooks.
The Svix Play API is free for everyone, both Svix customers and not, and you can start using it now by going to the Svix Play website. For more information on how to use it, please refer to the Svix Play API docs.