How do you contribute patches to Drupal core?
If the bug is in Drupal 7, do I have to also fix it in Drupal 8, and submit two patches?


If the bug is present in the version being developed (in this case Drupal 8), and the previous version (Drupal 7), then the bug should be first fixed the currently developed version, and then on the previous version(s).

If the bug is not present in the latest developed version, for example because the bug is for a function that has been removed, or that has been already changed, then the patch should be provided for the version before the currently developed one.

The workflow that is followed is:


First the patch is created, and submitted for reviews, for the most recent version, even if still under development (such as in the case of Drupal 8)
Once that patch is applied to Drupal, a patch that applies for the previous version is created, and submitted for reviews


You can create patches for two Drupal versions at the same time, but since the patch for the latest Drupal version could require changes, it is better to work on the patch for the currently developed version, than working on two different patches that both require to be changed.

See also: Backport Policy.


  Does this also apply to documentation bugs/improvements?


Yes, it does. Also in this case, if the currently developed version removed the function/method to which the documentation is referring, then the patch needs to be provided for the previous version.


  Do all patches also require a unit test?


If the patch is for the documentation, it doesn't require tests. The test bot running on http://qa.drupal.org checks the Drupal code after the patch is applied; if the patch introduces syntax errors (for example because the comment is closed before the needed), then the test bot will report an error about the patch before tests are run. 

If the patch is for a new feature, then the tests are required.

If the patch is to fix a bug, then the tests could be required from the maintainers, if there isn't already a test checking a specific feature. The test is generally necessary to avoid re-introducing the same bug when changing in future the same code. If the bug is merely a variable that is initialized, but never used from a function/method, then chances are the tests are not required.