London-Madrid, November, 2018
- Slow CI wastes developer time.
- Slow local tests make TDD impossible
git commit && git push
-
Wait 10 minutes
- ..or switch context and start a new thing
- (10 minutes later): red tests => switch context again
Standard setup: guard
or tests run after saving file
- Writes test. Save. Waits 3/4 seconds
- `uninitialized constant UserRegistrationService (NameError)`
- creates the file and the class. Hits save. Waits 3/4 seconds
- ``initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)`
- Fix the error. Hits save. Waits 3/4 seconds
...
Our intuitions about time are wrong. Becoming more efficient in our everyday work is our best move
- 15 minutes/day per developer
(being conservative)
10 developers: 2.5hs per day
1 week off per month (!)
<iframe src="https://giphy.com/embed/Kg22My7WG9vMc" width="480" height="270" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>Being more realistic:
A few more projects per year
<iframe src="https://giphy.com/embed/YQitE4YNQNahy" width="480" height="270" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>The bigger the team the more we need to invest in efficiency.
Our test suite is going to be even slower.
Red team has 10 people working full-time to make it slower
We are missing the benefits of unit testing
Unit tests ensure less coupled code
I use the term integrated test to mean any test whose result (pass or fail) depends on the correctness of the implementation of more than one piece of non-trivial behavior. (J.B. Rainsberger dixit)
- Anything that can change independently should be isolated
- Anything that is slow should be isolated.
-
Third party services
-
Rails
Testing state vs testing behaviour (message passing)
- Browser tests (integration)
- Database test (Models/Queries) (unit)
- Services tests (unit)
- Two test suites
- Different setup strategies
- Two tests suites: fast and slow
rake fast_test
- It doesn't make sense to have
norails_test
if we run it throughrails test
- DB calls and third-party calls are replaced by test doubles
- It can use real "service" objects but it must avoid touching the db or doing an HTTP request
- Setup: Probably factories
# Given
user = create(:user)
admin = create(:user, :admin)
# When
admins = User.admin
# Then
assert_includes(admins, admin)
refute_includes(admins, user)
- Fixtures?
- Sql dumps?
- There's room for improvement here