# Happiness And Testing

Most disucssions about the philosophy of testing start with definitions, but really testing is all about happiness.

Understanding of why we test underpins any strategy for testing.

## What do we want?

To be happy.

### Why will happy users make us happy?

We have an app, our app has users, things that we do or don't do affect the happiness of our users.

Unhappy users blame us for their unhappiness, no-one likes to be unhappy so they try to avoid unhappiness by avoiding 
things that make them unhappy, like our app, if they can't avoid our app they direct their unhappiness at it and us, 
and they share their unhappiness with others. 

Eventually we will be sad too.

### What makes users happy?

* Welcome new features
* Removal of bugs that frustrate them
* Improvement of heavily used features
* Removal of confusing unecassary features

### What makes users sad?

#### Loss of Face and Disappointment

* New features that don't meet expectations
* Old bugs that reappear

#### Frustration and Anger

* New bugs in existing functionality
* Failure to adapt to changing needs
* Outages
* Financial loss

All of the above are consequences of change to the app impacting users negatively.

### Why do we change the app?

Ironically, to make users happy.

We fix bugs, create new features and improve existing features.

Sometimes, however, the net outcome is to create more sadness than happiness, for example, we make a change that makes one user
very happy and a side effect of that change is we break something that makes 40 users very unhappy... a huge net loss
of happiness :(

### How can we ensure that changes create net happiness?

Minimise the amount of sadness in each change by reducing the risk of creating unintended sadness, and make sure our change is worth the risk.

## Brass Tacks

The best way to reduce sadness is testing (we're not going to stop changing the app). We want to reduce the risk of breakages by 
spotting those breakages before users are exposed to them. We can't avoid change and we can't avoid breaking things as we change them
but we can understand the risk of change and either reduce the risk of a change by ensuring that we test it thoroughly, or modify 
the change itself to lower its risk.

I don't want to get into a discussion about manual testing, surfice to say that a manual test relies on someone who is making a
change knowing all the things that they need to test and knowing that behaviour they see is incorrect. It also ties up that person
with all this knowledge doing the same testing over and over again whenever a change is made. This is fine for a small app
being developed by one person who never gets sick or hit by a bus, has a perfect memory, and nothing else to do, but not in the 
real world...

### When can we test?

#### Before making a change

Often described as **test driven development**, it's not always applicable but it can be of great value. Often you find that this 
will guide the structure help you write more testable code.

`Bug Fixing:` You first write a test that replicates the bug and then fix the code to make the test pass. This can give you a 
better understanding of the bug and challenge your assumptions about it.

`Extending Functionality:` You have to extend some functionality without breaking what exists already, write some tests that pass for the 
functionality you don't want to break (if you're lucky there will be some already) and some that fail for the functionality you haven't 
changed yet. By the time you've written the code all your tests should pass.

`New Features:` Write tests for the new functionality before you write the code, this will often help you to identify problems with
your approach up front.

#### During develpment

If you have a good set of tests you can run them locally when you make changes so that you know early if you've broken something.
For a large application this can be a cut down set of tests (which might also be a signal that your app is too big) and a continuous 
integration server can take up the slack by running the full battery.

#### Before and after a change or merge

This is where a continuous integration server comes in like [jenkins.lovelive.tv] which allows you run a full battery of tests against
main branches before deployment, or all changes to all branches [TODO].

* Before an internal deployment
* Before a production deployment
* After deployment
* Before exposing all users to a change

### How can we test?

**TODO** These all need some explanation and tips on approach added

* Server side unit tests
* Browser side unit tests 
* API tests
* End to end tests
* Smoke tests
* A/B testing [?]
* Benchmarking
* Manual testing

### How can we guage how confident we can be in our tests

* Coverage reporting

