Skip to content

How To Bypass Captcha for Unit Testing?

bypass captcha for software testing

A CAPTCHA is a test used in web pages to determine whether the user is human. The intention is to secure your application from bots and avoid automated attacks. When executing unit tests on your website, a captcha will prevent unit tests from working properly. 

So, how do you keep your site protected with captcha but also have passing unit tests? 

Since we are running our regression and end-to-end testing on our website and we have access to the code, we can make some code changes to allow unit tests to bypass captcha. For example, we can add hidden fields to our forms so the unit test can set these values and our back-end code can validate this and bypass captcha validation if detected.

For this example, we will use Google’s ReCAPTCHA V2 checkbox. ReCAPTCHA is a free service from Google that helps protect websites from spam and abuse and it is still fully supported and improved by Google.  

This code uses Laravel V8 to add Google’s captcha. We will use extra form parameters to let our back-end know whether we should bypass captcha or not. 

On the Front End:

This is the form with the hidden input type set to 1 (Display captcha). 

      <form class=”form-horizontal” role=”form” method=”POST” action=”{{ route(‘contact-request’) }}”>
             {!! csrf_field() !!}

             <div class=”form-group{{ $errors->has(‘name’) ? ‘ has-error’ : ” }}”>
                 <label class=”col-md-4 control-label”>Name</label>
                 <div class=”col-md-12″>
                     <input type=”text” class=”form-control” name=”name” value=”{{ old(‘name’) }}”>
                 </div>
             </div>

             <div class=”form-group{{ $errors->has(’email’) ? ‘ has-error’ : ” }}”>
                 <label class=”col-md-4 control-label”>E-Mail Address</label>
                 <div class=”col-md-12″>
                     <input type=”email” class=”form-control” name=”email” value=”{{ old(’email’) }}”>                 
                 </div>
             </div>

             <div class=”form-group{{ $errors->has(‘message’) ? ‘ has-error’ : ” }}”>
                 <label class=”col-md-4 control-label”>Message</label>
                 <div class=”col-md-12″>
                     <textarea class=”form-control” name=”message” rows=”3″>{{ old(‘message’) }}</textarea>
                 </div>
             </div>

             <div class=”form-group{{ $errors->has(‘g-recaptcha-response’) ? ‘ has-error’ : ” }}”>
                 <label class=”col-md-4 control-label”>Captcha</label>
                 <div class=”col-md-12″>
                     {!! app(‘captcha’)->display() !!}
                 </div>
             </div>
             
             <input type=”hidden” id = “captcha” name = “captcha” value = “1”>
             <div class=”form-group”>
                 <div class=”col-md-6 col-md-offset-4″>
                     <br/>
                     <button type=”submit” class=”btn btn-primary”>
                         Contact
                     </button>
                 </div>
             </div>
       </form>

On the Back-end:

The back-end code will check the value of the hidden input file. If it is set to zero, we need to skip captcha validation as it will mean our unit test is running. 

     public function contactRequest(Request $request) {

     $this->validate($request, [
           ‘name’ => ‘required’,
           ’email’ => ‘required|email’,
           ‘message’ => ‘required’,
           ‘captcha’ => ‘required’
     ]);

     $captcha = $request->input(‘captcha’);
     if($captcha) {

         $this->validate($request, [
             ‘g-recaptcha-response’ => ‘required|captcha’,
         ]);
     }

     // send email
     return “Email has been sent. We will reply you soon.”;
    }

Executing Unit Test:

When the unit testing script is executed, we can change the input value using a JavaScript snippet. We need to change this value before submitting the form. 

This is the JavaScript code to change the input value.  

document.getElementById(“captcha”).value = 0

Here is the execution of the test without executing the JavaScript snippet. The reCAPTCHA will detect this is a bot and will prevent unit tests to complete the form submission and fail the test. As we can see in the next animation, the unit test failed as the captcha was not solved. 

Here is the same test conducted after injecting the change on the unit test. The bypass will be ignored on the backend and the test will succeed. We can see a confirmation message at the end of the test. 

Google’s ReCaptcha V2 Bypass

In case we have a different environment for testing and production, Google’s reCAPTCHA provides a set of keys that can be used to bypass validation. This can be used in testing environments. In this case, all the requests will pass. 

The reCAPTCHA will show a warning message to ensure it’s not used for production traffic.

The keys we need to use to bypass reCAPTCHA on test environments are:

Site key: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI 

Secret key: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe 

Here is a short video to show this. We can see the captcha is showing the warning message. In case these keys are used in production, the user will detect this and report the problem. 

Conclusions 

The intention of CAPTCHA is to differentiate between humans and bots and protect against automated attacks. On unit testing, we do not want to bypass this verification. We want to be sure our application has a good set of regression tools that help us to have a robust and error-free application. 

As we saw in this post, there are some tricks (hidden input values, session values, cookies, etc.) that we can implement in our code to bypass captcha when running unit tests without eliminating captcha verification for final users. 

Jesús Serrano.

(Visited 73 times, 1 visits today)