Clerk logo

Clerk Docs

Ctrl + K
Go to clerkstage.dev

Test Emails and Phones

Write end to end tests by simulating OTP verifications.

Introduction

Most of Clerk's sign in and sign up flows involve verifying ownership of an email address or phone number via a one time passcode (OTP). To confirm that your integration works correctly, you can simulate verification flows without sending an email or SMS, by using reserved values in test mode.

Verification messages are used during Sign up, Sign in, and when adding an email address or phone number to an existing account.

Setup test mode

Every development instance has "test mode" enabled by default. If you need to use "test mode" on a production instance, you can enable it in Dashboard Application Settings page or via the Backend API.

You should not be using "test mode" on any instance that manages actual customers.

How to use test mode

Once test mode is enabled, all you need to do is use the following test numbers as part of your standard flow.

Email addresses

Any email with the `+clerk_test` subaddress is a test email address. No emails will be sent, and they can be verified with the code "424242"

Example test email addresses

jane+clerk_test@example.com

doe+clerk_test@example.com

Phone numbers

Any fictional phone number is a test phone number. No SMS will be sent, and they can all be verified with the code "424242".

Fictional phone numbers have the following structure:

+1 (XXX) 555-0100 to +1 (XXX) 555-0199

Example test phone numbers

+12015550100

+19735550133

Testing magic links in E2E suites is an uphill task. We recommend turning on email verification codes, and using that flow to authenticate your tests, the flows are very similar.

Code examples

Testing sign in via email code

Test Sign in with Email code
1
const testSignInWithEmailCode = async () => {
2
const { signIn } = useSignIn();
3
4
const emailAddress = "john+clerk_test@example.com";
5
const signInResp = await signIn.create({ identifier: emailAddress });
6
const { emailAddressId } = signInResp.supportedFirstFactors.find(
7
(ff) =>
8
ff.strategy === "email_code" && ff.safeIdentifier === emailAddress
9
)! as EmailCodeFactor;
10
11
await signIn.prepareFirstFactor({
12
strategy: "email_code",
13
emailAddressId: emailAddressId,
14
});
15
16
const attemptResponse = await signIn.attemptFirstFactor({
17
strategy: "email_code",
18
code: "424242",
19
});
20
21
if (attemptResponse.status == "complete") {
22
console.log("success");
23
} else {
24
console.log("error");
25
}
26
};

Testing sign up with phone number

Test Sign up with Phone number
1
const testSignUpWithPhoneNumber = async () => {
2
const { signUp } = useSignUp();
3
4
await signUp.create({
5
phoneNumber: "+12015550100",
6
});
7
await signUp.preparePhoneNumberVerification();
8
9
const res = await signUp.attemptPhoneNumberVerification({
10
code: "424242",
11
});
12
if (res.verifications.phoneNumber.status == "verified") {
13
console.log("success");
14
} else {
15
console.log("error");
16
}
17
};

Was this helpful?

Clerk © 2023