What is the difference between fakeAsync's tick() and done() in angular2 testing?

Those 2 things have nothing in common.

done is just a callback to let your test runner know when an async operation is done.

For example:

it('should wait for this promise to finish', done => {
  const p = new Promise((resolve, reject) =>
    setTimeout(() => resolve(`I'm the promise result`), 1000)
  );

  p.then(result => {
    // following will display "I'm the promise result" after 1s
    console.log(result);

    // this let your test runner know that it can move forward
    // because we're done here
    // the test will take 1s due to the setTimeout at 1000ms
    done();
  });
});

You might also use async for that (just to avoid calling done manually):

it(
  'should wait for this promise to finish',
  async(() => {
    const p = new Promise((resolve, reject) =>
      setTimeout(() => resolve(`I'm the promise result`), 1000)
    );

    p.then(result =>
      // following will display "I'm the promise result" after 1s
      console.log(result)
    );

    // notice that we didn't call `done` here thanks to async
    // which created a special zone from zone.js
    // this test is now aware of pending async operation and will wait
    // for it before passing to the next one
  })
);

Now, fakeAsync gives you control over time (which is really powerful) so you can write your tests in a synchronous way, and simulate that time goes by to avoid waiting for setTimeout for example:

it(
  'should wait for this promise to finish',
  fakeAsync(() => {
    const p = new Promise((resolve, reject) =>
      setTimeout(() => resolve(`I'm the promise result`), 1000)
    );

    // simulates time moving forward and executing async tasks
    flush();

    p.then(result =>
      // following will display "I'm the promise result" **instantly**
      console.log(result)
    );

    // notice that we didn't call `done` here has there's no async task pending
  })
);

So just to be clear, with fakeAsync in the last example, if the setTimeout was set on 10s, the test would still be executed instantly.