Deploy first, write tests, then develop. This turns [[waterfall]] on its head.
[[project scoping]]
## Waterfall
Waterfall is a software development process popular before around 2019 (and still practiced intentionally or unintentionally by many) where the product is developed, then tests are written, then it is deployed. This typically takes 6-9 months, so by the time the app is deployed it may be irrelevant. Further, the investment is significant before meaningful user feedback can be collected.
Contrast with [[Agile]].
## Agile
Agile is a software development process that is probably the dominant paradigm for software development today (although many teams say they are Agile when really they are still practicing [[waterfall]]).
## minimum viable product
The purpose of an MVP (minimum viable product) is to get feedback from users and test viability of the product.
A cloud native MVP should include
- hint of scalability (shared session for web apps)
- basic monitoring
- communicated [[service level agreement]]
- blue/green deploys
## service level agreement
## refactor
Refactoring is the process of restructuring an existing body of code, altering its internal structure without changing its external behavior.
"Red, green, refactor" means write a test, then write code to pass the test, then refactor the code while maintaining green status.
> [!Tip]- Additional Resources
> - [Refactoring](https://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Signature-ebook/dp/B07LCM8RG2[]())
> - [Design Patterns](https://www.amazon.com/dp/B000SEIBB8)
> - [Refactoring to Patterns](https://www.amazon.com/Refactoring-Patterns-Joshua-Kerievsky/dp/0321213351)
## test driven development
Test driven development is a software development paradigm in which test are written before code.
Testing should be done early and often. Testing is a continuous process that should be performed at each stage of software development.
### unit test
A unit test covers the low level aspects of a system. For each method `foo()` there should be another method `testFoo()`.
### integration test
Integration tests check that the modules work together in combination.
### acceptance test
Acceptance tests are tests performed by the user (or product owner) to check that the delivered system meets their needs. Often these are written first to inform integration tests and unit tests. This is called **outside-in testing**.
### code coverage
Full code coverage is when tests cover all possible states of the code. Components of coverage include
- **statement coverage**: all statements have been executed by a test
- **branch (edge) coverage**: each edge in a program's control flow graph have been executed
- **condition coverage**: like branch coverage but with emphasis on all combinations of conditions (if/then branches and guard clauses in code)
- **path coverage**: all paths in a program's control flow graph have been executed multiple times.
### test double
A test double is an object that "doubles" an object in code for the purpose of testing.
- **stub**: replaces the real component with a canned answer
- **spy**: mock or stub that records, implements the 2 or 3 methods of interest
- **mock**: replaces real component with pre-programmed expectations
- **fake**: replaces real component with shortcuts
- **dummy**: placeholder object, never actually used
### dependency injection
> [!Tip]- Additional Resources
> - [Test Driven Development by Kent Beck](https://www.amazon.com/Test-Driven-Development-Addison-Wesley-Signature-ebook/dp/B0CW1JBTHM/)
## continuous integration
Continuous integration simply means running the test suite with each commit.
## continuous delivery
Continuous delivery allows teams to deploy code directly.
## retrospective
A retrospective is a typically done at the end of each week and/or software iteration cycle. Often the team reviews completed and outstanding action items.
Analogous to a [[pause and reflect]].
## best practices
These are best practices in [[software engineering]], loosely based on the book [Extreme Programming Explained](https://www.amazon.com/Extreme-Programming-Explained-Embrace-Change-ebook/dp/B00N1ZN6C0) by Kent Beck.
- Simple design
- [[Test driven development]]
- [[Refactor]] ruthlessly
- Short releases and [[minimum viable product]]
- On-site customer, small [[user stories]]
- [[continuous integration]]
- [[continuous delivery]]
- [[retrospective]]
- collective ownership (high bus factor)
At a high level, the most important practices are
- flow of work (consistent, reliable productivity "fast forever")
- fast feedback loops
- culture of continual experimentation and learning