Using Test Credentials and Magic Phone Numbers to Test Twilio Applications
Time to read: 6 minutes
A common problem when developing an application that uses Twilio services is how to effectively test it. Making real requests to Twilio for testing purposes is something that can be useful when done sparsely, but it is not ideal as a general approach to testing because it can end up being expensive. Also, when testing how your application responds to errors you are going to find that it is very hard to replicate all the possible error conditions that can occur in SMS or Voice communication.
In this article you are going to learn how to work with your Twilio Test Credentials to be able to send fake, yet realistic requests to Twilio that have a predictable result, and more importantly, are 100% free.
Tutorial requirements
To follow this tutorial you need the following components:
- Python 3.6 or newer. If your operating system does not provide a Python interpreter, you can go to python.org to download an installer.
- A phone with SMS support.
- A Twilio account. If you are new to Twilio create a free account now. If you use this link you’ll receive $10 in credit when you upgrade to a paid account (you can review the features and limitations of a free Twilio account).
Running the example application
For this tutorial we are going to use a simple Flask application that sends SMS. This application is available on GitHub. If you have git
installed, you can grab a copy as follows:
If you prefer to download the application from your web browser, click this download link.
Once you have the application installed, open a terminal and change to this directory:
Next we are going to create a virtual environment and install the dependencies for this application on it. If you use a Linux of Mac computer:
If you are using a Windows computer, use the following commands:
This application uses a .env (dot-env) file for configuration. Create a .env file in this directory and define four variables in it:
You can find out the values of the first two variables that are correct for your account by logging in to your Twilio Console and then clicking “Settings” on the left sidebar. Scroll down until you see the “API Credentials” section.
Copy the “Account SID” and “Auth Token” from the “LIVE Credentials” box into your .env file.
For the FROM_NUMBERS
variable, enter the Twilio phone number associated with your account. If you don’t have a phone number on your account, you can buy one just for this tutorial (if you are using a trial account you’ll be spending your trial credit for this, not real money). Enter the number in full E.164 format. For example, if your Twilio number is +12345678900, you would enter:
If you have more than one number in your Twilio account, you can enter all of them separated by commas:
For the TO_NUMBERS
variable, enter your mobile phone number. Here you can also enter a list of numbers you would like to send SMS to. Keep in mind that if you are using a trial account, Twilio requires that all numbers that will receive SMS be verified.
Once you have the four variables set in your .env file, save the file.
Now we are ready to start the application, with the flask run
command:
You should see the Flask server running as follows:
With the application still running, open your web browser and enter http://localhost:5000 in the address bar, and you should see the Send SMS Demo application in its full glory:
The Sender and Recipient dropdowns show the numbers that you configured in the .env file. If you select the sender and recipient numbers you would like to use, type a message and hit the “Submit” button, an SMS will be sent.
Make sure you can send yourself a message before continuing on to the next section.
Using Test Credentials
The main function in the example application is the send_sms()
function. You can see the implementation of this function in file app.py below:
The twilio.messages.create()
function comes from the Twilio Helper Library for Python, and is where the request to the Twilio service is made.
How robust do you think this function is? You can probably guess that having a single line code isn’t as robust as it can be. We would like this function to be able to withstand all possible error conditions, but to achieve that we need a way to generate all these possible failures in a controlled testing environment, and ideally without having to spend money on Twilio services.
We are going to address this need using our Test Credentials. Stop the example application by pressing Ctrl-C
on the terminal window where it was running. Then open the .env file again, and change the Account SID and Auth Token variables to the settings that appear on the ‘TEST Credentials” box in your Settings page.
When you use your test credentials, Twilio will accept your requests and process them normally, but it won’t actually do anything. That means that no SMS or phone calls will be made, and your account will not generate any charges.
Your test credentials function in a completely different environment than your live ones, with no connection between the two. In particular, any phone numbers that are associated with your live account are not going to be recognized under your test credentials. This gives us an opportunity to try our first error condition, using an invalid sender phone number.
Start the application again by running flask run
, and try to send yourself another SMS. Your web browser should now show a bad looking error message.
To find what was the error we have to look in the terminal window where the Flask application is running. The error should look like this:
This is a long and obscure error message, but you can ignore most of it and concentrate on the exception raised, which is shown near the bottom. In this case it was a TwilioRestException
, and the error message is actually self-explanatory:
So now we know that when there is an error, this application just crashes by raising a TwilioRestException
with a useful error message.
If we look in the place where the send_sms()
function is invoked in app.py, we can see that this code is already prepared to handle exceptions of type RuntimeError
and show them as errors to the user via Flask’s message flashing mechanism:
One improvement we can make to this application is to catch the TwilioRestException
and raise a RuntimeError
exception in its place. Let’s make this change in the send_sms()
function, and also add the import for the TwilioRestException
at the top of the file:
The msg
and code
attributes of the Twilio exception include the message and the numeric code for the error, which we format nicely into the RuntimeError
using an f-string.
Stop and restart the Flask application and try to send yourself an SMS one more time. Now the output is much nicer:
Magic numbers
The application is now able to handle unexpected errors in a more dignified way, but so far the only error we can replicate is the one that comes up when we use an invalid phone number as a sender. The test credentials do not give us a way to generate other error conditions, and more importantly, we have lost the ability to send a successful SMS, since now all messages fail.
To handle all these different scenarios, Twilio provides magic numbers, special phone numbers that have predefined behaviors.
For SMS, Twilio supports the following magic numbers as senders:
Number |
Behavior |
+15005550001 |
Invalid phone number. |
+15005550006 |
Valid number. |
+15005550007 |
The number is not owned by your account or not SMS capable. |
+15005550008 |
The number has a full SMS queue. |
Any other number |
The number is not owned by your account or not SMS capable. |
As receivers, the following SMS magic numbers are available:
Number |
Behavior |
+15005550001 |
Invalid phone number. |
+15005550002 |
Cannot route to this number. |
+15005550003 |
Your account does not have international permissions. |
+15005550004 |
The number is in the blocked list. |
+15005550009 |
The number is not SMS capable. |
Any other number |
Valid number. |
Let’s add all of these magic numbers to our .env configuration. Replace the values for the FROM_NUMBERS
and TO_NUMBERS
with the following values:
After making these changes to your .env file, remember to stop the Flask server and restart it.
Now by selecting combinations of sender and receiver magic numbers we can generate all possible outcomes, valid or invalid, and all without incurring any charges with Twilio.
Conclusion
In this article, you have learned how to use Twilio test credentials and magic numbers to test sending of SMS. Twilio also provides magic numbers for making phone calls, and for buying phone numbers.
I hope you find the use of test credentials and magic numbers a useful technique to add to your bag of tricks when working with Twilio!
Miguel Grinberg is a Python Developer for Technical Content at Twilio. Reach out to him at mgrinberg [at] twilio [dot] com if you have a cool Python project you’d like to share on this blog!
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.