3

I'm testing an AJAX application where we need to handle a temporary loss of connection to the server or other errors (i.e. like in Gmail or Google Calendar.) What's a good way to simulate this in testing?

For example, is there a browser plugin that will allow one to temporarily "turn off" the internet connection for a tab? I do all my debugging in Chrome so it would be particularly helpful if someone could offer a suggestion for that browser.

Other options I've tried are toggling the network connection to a VM to the server, or shutting down the server and restarting it, neither of which is very lightweight or easy for testing (the latter also doesn't preserve any state.)

Clarification: I'm not interested in how to test disconnection handling in test code. I want to create a disconnection to test when running my app. Ideally, it could be something easily toggled in one tab of my browser that doesn't involve borking my entire internet connection.

Andrew Mao
  • 35,740
  • 23
  • 143
  • 224

3 Answers3

0

On this question, knowing which framework you are using to test would be a very good thing. For the rest, if the AJAX stuff is handled by an XMLHttpRequest object, there is very little you can do, as once the request has fired, you cannot control it anymore. If you are using a framework such as jQuery, consider juking the events. This involves firing an event in a synthetic fashion. In order to do, if your event handlers are public in scope (which they should be if you are writing maintainable code), you should be able to fire them. If not, make them public.

Failing that, you can act on the server side by:

  1. Setting up a "test mode" where your server drops connection at a specific time
  2. Consider routing through a configurable proxy (nginx?) to effectively implement step 1 without modifying your server
  3. Fire your disconnection handler by itself synthetically rather than the event. You know that your event handler for XMLHttpRequest failing is working - that's assured by your browser not being buggy. What you need to test is if your function works.
Sébastien Renauld
  • 19,203
  • 2
  • 46
  • 66
  • Assume that I've covered my bases in test code. I want to actually make sure that stuff works when the connection is dropped now. – Andrew Mao May 14 '13 at 15:44
  • @AndrewMao: are you listening for a dropped connection using the XMLHttpRequest onreadystatechange event? If so, you can consider this to work and instead call the function bound to that synthetically (i.e. faking a disconnection through JS). Wanting to drop a connection to test this makes you test **your browser's XMLHttpRequest** along with your code, which is not what you are after - and is redundant, as most browsers have unit tests for this object already. – Sébastien Renauld May 14 '13 at 15:52
  • I agree with your principle, but sometimes it's good just to be able to see that your app works as intended :) – Andrew Mao May 14 '13 at 15:53
  • @AndrewMao: `myXHR.readyState = 4; myXHR.status = 500; myXHR.onreadystatechange.apply(myXHR,[]);`. Done. – Sébastien Renauld May 14 '13 at 16:01
0

When we've had to do this in the past we usually have the nic settings open and disable the adapter. Some of the guys w/laptops would run on a wired connection and just unplug it.

You could also use netsh:

netsh interface set interface <interface name> DISABLED/ENABLED 
Striker
  • 339
  • 1
  • 3
  • 13
  • That is doable, but in my case (in development) the server and client are on the same computer :) – Andrew Mao May 14 '13 at 15:52
  • Since you're running both client and server locally you might want to add an entry to your hosts file and set it to the IP address of your machine. Use that to access your local server and then when you want to simulate the disconnect simply comment out the entry in the hosts file and save it. Timing is going to be tricky though... – Striker May 14 '13 at 15:55
0

I do not know any ready solution, but I have an idea how to achieve that.

If your server is running on linux you could write a simple script which would add a rule to iptables blocking the traffic on ip or tcp level. Then just run the script to block on unblock the traffic.

I would set up a virtual host on a different port, put there a few scripts to block allt raffic, unblock traffic, throttle etc, and then add those scripts to bookmarks to have a fast way to run them. Those scripts would just call iptables with different parameters.

SWilk
  • 3,261
  • 8
  • 30
  • 51