From 3c0844559d20de73df5a9ccd021cca7eeff32bc1 Mon Sep 17 00:00:00 2001
From: Tim Otten <totten@civicrm.org>
Date: Tue, 10 Oct 2017 12:42:39 +0100
Subject: [PATCH] testing/index.md - Rewrite

 * Provide a better visualization of the the different test suites
 * Migrate setup instructions from https://github.com/civicrm/civicrm-core/blob/master/tests/README.md
---
 docs/testing/index.md | 185 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 184 insertions(+), 1 deletion(-)

diff --git a/docs/testing/index.md b/docs/testing/index.md
index a53455da..1e67143f 100644
--- a/docs/testing/index.md
+++ b/docs/testing/index.md
@@ -1 +1,184 @@
-The easiest way to get set up to run the automated tests is to use [buildkit](/tools/buildkit.md) which will install the tools necessary for running the tests and creating local CiviCRM sites with [civibuild](/tools/civibuild.md).
+## Overview
+
+The CiviCRM suite spans the full stack -- it includes low-level helpers and user-facing applications; it includes
+server-side PHP and client-side Javascript; it touches multiple business areas (such as contributions, mailings, and
+cases); it includes a common core project and an ecosystem of add-ons.
+
+Depending on the scope of the test and the relevant language, one chooses among these tools:
+
+<table>
+  <thead>
+    <tr>
+      <th></th>
+      <th>Description</th>
+      <th>PHP</th>
+      <th>Javascript</th>
+      <th>Other</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>
+        Unit Test
+      </th>
+      <td>
+        Basic testing of a single function or class<br/>
+        <b>Trade-off</b>: <em>Fast but minimal/synthetic environment</em><br/>
+        <b>Good for testing</b>: <em>Helpers, libraries</em>
+      </td>
+      <td>
+        <a href="phpunit">PHPUnit</a>
+      </td>
+      <td>
+        <a href="karma">Karma</a>
+      </td>
+      <td>
+      </td>
+    </tr>
+    <tr>
+      <th>
+        Headless Test
+        </th>
+      <td>
+        Mid-level testing with headless database<br/>
+        <b>Trade-off</b>: <em>Mid-level speed and realism</em><br/>
+        <b>Good for testing</b>: <em>Data management APIs, portable backend services</em><br/>
+      </td>
+      <td>
+        <a href="phpunit">PHPUnit</a>
+      </td>
+      <td>
+      </td>
+      <td>
+      </td>
+    </tr>
+    <tr>
+      <th>
+        End-to-End Test (E2E)
+      </th>
+      <td>
+        Full-stack testing with CMS, HTTPd, etc<br/>
+        <b>Trade-off</b>: <em>Slow but realistic environment</em><br/>
+        <b>Good for testing</b>: <em>Screens, pageflows, integrations</em><br/>
+      </td>
+      <td>
+        <a href="phpunit">PHPUnit</a><br/>
+        <a href="codeception">Codeception</a><br/>
+        <s><a href="webtest">Selenium</a></s>
+      </td>
+      <td>
+        <a href="protractor">Protractor</a><br/>
+        <s><a href="qunit">QUnit</a></s>
+      </td>
+      <td>
+        <a href="upgrades">Upgrades</a><br/>
+        <a href="manual">Manual</a><br/>
+      </td>
+    </tr>
+  </tbody>
+</table>
+
+!!! caution "Be mindful of test types"
+
+    Each style of testing (unit, headless, E2E) has distinctive practices.  For example, headless tests periodically reset the entire database, but
+    E2E tests don't. These concepts are discussed in more detail below.
+
+## Setup
+
+Many test suites require information about your local development environment.  For example, headless tests may require credentials for an extra
+MySQL database, and end-to-end tests may require credentials for a CMS.
+
+The test tools obtain this information via [cv](https://github.com/civicrm/cv).  If your build was created by [buildkit](/tools/buildkit.md) and
+[civibuild](/tools/civibuild.md), then `cv` can fetch *all* the information automatically. Other builds may require some manual configuration.
+
+To inspect the configuration, run:
+
+```bash
+$ cd /path/to/civicrm
+$ cv vars:show
+```
+
+This should display a number of properties, including:
+
+* Credentials for an empty test database (`TEST_DB_DSN`)
+* Credentials for an administrative CMS user (`ADMIN_USER`, `ADMIN_PASS`, `ADMIN_EMAIL`)
+* Credentials for a non-administrative CMS user (`DEMO_USER`, `DEMO_PASS`, `DEMO_EMAIL`)
+
+If these are missing or blank, then you need to fill them in. Initialize and edit the configuration file:
+
+```bash
+$ cv vars:fill
+$ vi ~/.cv.json
+```
+
+!!! tip "Tip: Database snapshots"
+
+    Many tests interact with the database. In case they mess up the database, you should retain a snapshot of your baseline DB.
+
+    If you used `civibuild`, it automatically retained a DB snapshot when you last (re)installed the site.
+    See [civibuild restore](/tools/civibuild.md#rebuild) for more information.
+
+!!! tip "Tip: Multi-user systems"
+
+    By default, `cv` uses the configuration file `~/.cv.json`. However, if this build is accessed by many user accounts, then
+    you can use a shared configuration file. Run `export CV_CONFIG=/path/to/shared/file.json` and then call `cv vars:fill`.
+
+## Architecture
+
+Most automated tests require access to some mix of **resources** -- such as source-code files, databases, or URLs.  To access these resources, test
+frameworks should build on the [cv](https://github.com/civicrm/cv) command.
+
+There are three types of tests. Each handles these resources differently.
+
+### Minimal unit test {:#unit}
+
+A minimal **unit test** focuses on testing a discrete technical artifact, such as a function, class, or file.  Minimal unit tests are **loosely**
+**coupled**, and they generally shouldn't require an external service (such as a database or web-server).  The narrow scope and loose-coupling makes
+these **fast** -- so you can execute a large suite of tests in a short time.  However, it also makes them **less representative**.  This type of
+testing is ideal for helpers, utilities, and libraries which have innately low coupling.  They're also useful if you need to test a large range of
+possible inputs/permutations.
+
+!!! tip "Unit tests and safety"
+
+    In a minimal unit-test, running the test should have no side-effects -- ie it should not change data-files or database tables.
+
+!!! tip "Unit tests and bootstrap"
+
+    In a framework like `phpunit` or `karma`, a minimal unit test might call `cv php:boot --level=classloader`
+    or `cv path -d [civicrm.root]` to gain access to Civi's source code.
+
+### Headless test {:#headless}
+
+The most common kind of automated test in `civicrm-core` is a **headless test**.  A headless test focuses on a combination of artifacts, such as
+multiple PHP classes and a database.  Headless tests have a *nearly complete* CiviCRM environment, but some elements (such as the web server and CMS)
+are omitted.  This is ideally suited to testing data-management APIs (where the DBMS is an important part of the system) and other portable services
+(where you wouldn't expect the CMS or HTTPD to influence behavior).
+
+!!! tip "Headless tests and safety"
+
+    In a headless unit-test, the test takes ownership over a private, test-only, *headless* copy of CiviCRM.  Headless tests commonly take steps to
+    keep the database at a clean baseline, such as (a) rolling back a SQL transaction or (b) truncating a few data tables or (c) resetting the entire
+    database.
+
+!!! tip "Headless tests and bootstrap"
+
+    In a framework like `phpunit` or `codeception`, a headless test might call `cv php:boot --level=full`. To avoid bootstrapping a full CMS, it
+    would need an environment variable `CIVICRM_UF=UnitTests`.
+
+### End-to-end test {:#e2e}
+
+An **end-to-end test** (E2E) focuses on testing a full stack, including some combination of CRM, CMS, web-server, file-system, database, and web-browser.
+These tests are the most **representative** of real-world usage, because they tie together so many components.  However, this **high coupling** also makes
+them brittle (because a design-change or fault in any part of the system can disrupt the expected flow).  This type of testing is ideal for screens,
+pageflows, and integrations which have innately high coupling.
+
+!!! tip "End-to-end tests and safety"
+
+    In an E2E test, the test runs against an active, local CiviCRM installation.  By default, each test makes **persistent** changes, which can
+    create side-effects for other tests. Be conscientious about (a) checking pre-conditions (in case other tests have side-effects) and
+    (b) cleaning up to prevent side-effects (that might break other tests).
+
+!!! tip "End-to-end tests and bootstrap"
+
+    In a framework like `phpunit` or `codeception`, an E2E test might call `cv php:boot --level=full`. However, it would not need to explicitly
+    set `CIVICRM_UF`. Depending on the active CMS, this value is determined automatically.
-- 
GitLab