Monday, January 16, 2012

Testing Facebook Login with Selenium

On EatDifferent, I give users two options for signing up: Facebook, for people that like the convenience of using FB to sign in everywhere, and email+password, for people that hate Facebook. I see about 50/50 usage for these options, so they are both equally important — which means testing both of them are equally important.

Until today, however, I only had integration tests for email signup and login, because, well, I was afraid. All I have to do for email login testing is enter a few text fields, but for Facebook testing, I would need to navigate to the Facebook popup window and manipulate *their* DOM, and I would need a test user account that was really and a truly a test user (and not my cat, who actually is surprisingly active on Facebook). As I was making some changes that affected Facebook users today, I decided it was time to face my fears. Good thing I did, because testing Facebook login turned out to be pretty easy. Read on to see how I did it...

Create a Test User

In the land of old, creating a test Facebook user meant digging up an old email address and signing up with your cat's details. That kind of sucked, since you only have so many old email addresses, and it wasn't exactly Facebook TOU-friendly. Thankfully, Facebook introduced a way earlier this year to create multiple test users, both programmatically and from the developer dashboard. For the purpose of my tests, I only need one test user, so I created him semi-manually with these steps:

  • Go to http://developers.facebook.com/apps, and select your app. Click 'Edit app' and then 'Roles' on the left-hand side.
  • Under 'Test Users', click 'Add'. Select '1' and don't select 'Authorize this app' (if your purpose is to test authorization).
  • Once created, click 'Modify' in the 'Test Users' section. You'll see a table with information about the test user, like their name (which you can change to something snappier, like "Sharky Shark" :) and ID.
  • Now you need to find out the user's password, so you can enter that with Selenium. First, get an access token for your app by putting this URL in the browser and replacing the client_id and client_secret with your app key and app secret:
    https://graph.facebook.com/oauth/access_token?client_id=APP_KEY&client_secret=APP_SECRET&grant_type=client_credentials
  • Now paste this URL in the browser, replacing the ID with your test user ID, access_token with the string you just got, and password with your desired test password:
    https://graph.facebook.com/TEST_USER_ID?password=TEST_PASSWORD&method=post&access_token=ACCESS_TOKEN
  • Click 'Login' in the users table so that you're logged into Facebook as them. Visit their profile, take note of their email address, and change any desired fields (depending on what your app uses - I gave mine a profile pic and location).

Presto, now you have a test user.

Test the Facebook Popup

For my integration tests, I use Selenium with its Python API and Python's unittest module.

For my FacebookTests test case, I extend my BaseTests class and add two test methods, one for testing authorization and the other for testing login.


Those test methods use the FacebookDom helper class (an extension of my DomHelper class) for finding and manipulating the Facebook window and DOM. Note that after the user has granted the authorization, Facebook will no longer ask for authorization unless the user specifically revokes it - so my do_authorize_flow function checks to see if the auth button is actually there before trying to click it.


Ta-da, now you have a tested Facebook authorization and login flow! Some may argue that you shouldn't try to test 3rd party APIs because they may go down or be flaky or such and that you should mock them out instead, but I'm of the philosophy that integration tests should try to mimic the production environment as much as possible. And hey, I want to know if Facebook goes down, changes their response, or becomes flaky.

No comments: