Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to...
Transcript of Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to...
![Page 1: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/1.jpg)
Beautiful Testsby Bruce A. Tate
icanmakeitbe*er
It’s good to be here... I almost wasn’t.
![Page 2: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/2.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 3: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/3.jpg)
Test all of your code with beautiful, dry, fast tests
Many of us come from a testing culture... that’s good.
Testing tools are in their infancy... that’s bad.
This talk is about a set of band aids we added to existing tools until ExUnit can come around.
![Page 4: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/4.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 5: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/5.jpg)
if it is worth writing
![Page 6: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/6.jpg)
if it is worth writing it is worth testing
![Page 7: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/7.jpg)
don’t let your customers test your code
![Page 8: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/8.jpg)
we use excoveralls
https://github.com/parroty/excoveralls
![Page 9: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/9.jpg)
we use setup
![Page 10: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/10.jpg)
defmodule Chat.Mixfile do defp deps do [{:excoveralls, only: :test}] end defp test(args) do Mix.Task.run("test", []) Mix.shell.info("") Mix.shell.info("$ mix coveralls -‐ coverage overview") Mix.shell.info("$ mix coveralls.detail FILENAME -‐ line-‐by-‐line coverage of file") end
defp cli_env do [coveralls: :test, "coveralls.detail": :test] endend https://gist.github.com/batate/fd9e7569b3861a80a0b3
![Page 11: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/11.jpg)
we use report
![Page 12: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/12.jpg)
[imbe] (develop=) ➔ mix coverallsCompiled lib/chat/room_supervisor.exCompiled lib/chat.exCompiled lib/chat/attachment_cache.exCompiled lib/chat/socket/handler.exCompiled lib/chat/room.exGenerated chat.app.....................................................................................................
Finished in 8.1 seconds (2.4s on load, 5.6s on tests)101 tests, 0 failures
Randomized with seed 167783----------------COV FILE LINES RELEVANT MISSED100.0% lib/chat.ex 98 18 0100.0% lib/chat/attachment_cache.ex 221 81 0100.0% lib/chat/crypto.ex 47 17 0100.0% lib/chat/http/process.ex 34 13 0100.0% lib/chat/models.ex 16 4 0100.0% lib/chat/models/company.ex 89 1 0100.0% lib/chat/models/multi_attachment.ex 45 13 0 0.0% lib/chat/models/page.ex 11 0 0100.0% lib/chat/models/survey.ex 83 4 0100.0% lib/chat/models/survey_question.ex 80 12 0100.0% lib/chat/models/survey_response.ex 66 8 0100.0% lib/chat/models/token.ex 51 8 0100.0% lib/chat/models/user.ex 80 7 0100.0% lib/chat/mongo.ex 118 37 0100.0% lib/chat/mongo/cursor.ex 92 20 0100.0% lib/chat/mongo/model.ex 105 39 0100.0% lib/chat/mongo/process.ex 176 65 0100.0% lib/chat/mongo/query.ex 54 16 0100.0% lib/chat/mongo/worker.ex 75 14 0 0.0% lib/chat/repo.ex 14 0 0100.0% lib/chat/room.ex 786 329 0100.0% lib/chat/room_supervisor.ex 29 7 0100.0% lib/chat/router.ex 15 2 0100.0% lib/chat/socket.ex 20 2 0100.0% lib/chat/socket/handler.ex 363 169 0100.0% lib/chat/socket/process.ex 87 25 0100.0% lib/chat/socket/sockjs.ex 62 20 0100.0% lib/chat/topic.ex 167 41 0100.0% lib/chat/topic/gc.ex 46 13 0[TOTAL] 100.0%----------------
$ mix coveralls - coverage overview$ mix coveralls.detail FILENAME - line-by-line coverage of file
This is hard to read unless you have zeros on the right hand side!
![Page 13: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/13.jpg)
[imbe] (develop=) ➔ mix coverallsCompiled lib/chat/room_supervisor.exCompiled lib/chat.exCompiled lib/chat/attachment_cache.exCompiled lib/chat/socket/handler.exCompiled lib/chat/room.exGenerated chat.app.....................................................................................................
Finished in 8.1 seconds (2.4s on load, 5.6s on tests)101 tests, 0 failures
Randomized with seed 167783----------------COV FILE LINES RELEVANT MISSED100.0% lib/chat.ex 98 18 0100.0% lib/chat/attachment_cache.ex 221 81 0100.0% lib/chat/crypto.ex 47 17 0100.0% lib/chat/http/process.ex 34 13 0100.0% lib/chat/models.ex 16 4 0100.0% lib/chat/models/company.ex 89 1 0100.0% lib/chat/models/multi_attachment.ex 45 13 0 0.0% lib/chat/models/page.ex 11 0 0100.0% lib/chat/models/survey.ex 83 4 0100.0% lib/chat/models/survey_question.ex 80 12 0100.0% lib/chat/models/survey_response.ex 66 8 0100.0% lib/chat/models/token.ex 51 8 0100.0% lib/chat/models/user.ex 80 7 0100.0% lib/chat/mongo.ex 118 37 0100.0% lib/chat/mongo/cursor.ex 92 20 0100.0% lib/chat/mongo/model.ex 105 39 0100.0% lib/chat/mongo/process.ex 176 65 0100.0% lib/chat/mongo/query.ex 54 16 0100.0% lib/chat/mongo/worker.ex 75 14 0 0.0% lib/chat/repo.ex 14 0 0100.0% lib/chat/room.ex 786 329 0100.0% lib/chat/room_supervisor.ex 29 7 0100.0% lib/chat/router.ex 15 2 0100.0% lib/chat/socket.ex 20 2 0100.0% lib/chat/socket/handler.ex 363 169 0100.0% lib/chat/socket/process.ex 87 25 0100.0% lib/chat/socket/sockjs.ex 62 20 0100.0% lib/chat/topic.ex 167 41 0100.0% lib/chat/topic/gc.ex 46 13 0[TOTAL] 100.0%----------------
$ mix coveralls - coverage overview$ mix coveralls.detail FILENAME - line-by-line coverage of file
The bottom line makes it easier for our devs to do the right thing.
![Page 14: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/14.jpg)
detailed report
![Page 15: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/15.jpg)
... defp receive_nonmember(false, conn, s, chat) do room = Room.join(s.room, chat, s.user, s.token)
if s.role != "admin" do # Filter unpublished questions questions = Enum.filter(room.questions, & &1.published)
# Filter hidden messages questions = Enum.map(questions, fn question -> answers = Enum.reject(question.answers, & &1.hidden) %{question | answers: answers} end)
# Filter blocked members ...
![Page 16: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/16.jpg)
Test all of your code with ??? beautiful, dry, fast tests
When we decided to code Elixir for our production servers, we had a decision to make. want a good elixir... compressed schedules
![Page 17: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/17.jpg)
Think Philosophy, not the Tool Box
We want to show you real code so that means context. But the tool set doesn’t matter. That said...
![Page 18: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/18.jpg)
•ExUnit (our goal: 100%)
•ShouldI (batate/shouldi)
•Blacksmith (batate/blacksmith)
We use...
We hope to push as much of this into shouldi as possible
![Page 19: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/19.jpg)
•ExUnit (our goal: 100%)
•ShouldI (batate/shouldi)
•Blacksmith (batate/blacksmith)
We use...
![Page 20: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/20.jpg)
+ Fast+ Pretty Assertions+ Templates
Oh... About Exunit
![Page 21: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/21.jpg)
Oh... About Exunit
+ Fast+ Pretty Assertions+ Templates
- Not Dry- Chaotic- Language / Syntax
![Page 22: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/22.jpg)
Oh... About Exunit
+ Fast+ Pretty Assertions+ Templates
- Not Dry- Chaotic- Language / Syntax Not Yet!
Our goal is to work directly with the core team to improve tests where we can help.
![Page 23: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/23.jpg)
setup do # universal setupend test "a get" do ...end test "logged in get" do login_user ...end test "logged in post" do login_user ...end
setup do # universal setupend test "a get" do ...end test "logged in get" do login_user ...end test "logged in post" do login_user ...end
![Page 24: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/24.jpg)
setup do # universal setupend test "a get" do ...end test "logged in get" do login_user ...end test "logged in post" do login_user ...end
setup do # universal setupend test "a get" do ...end test "logged in get" do login_user ...end test "logged in post" do login_user ...end
![Page 25: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/25.jpg)
setup do # universal setupend test "a get" do ...end test "logged in get" do login_user ...end test "logged in post" do login_user ...end
![Page 26: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/26.jpg)
setup do # universal setupend test "a get" do ...end test "logged in get" do login_user ...end test "logged in post" do login_user ...end Not Dry
This becomes a big problem as overarching tests get nested. in models: persistent vs not; error vs happy path; etc. So setup code can be a big pain
![Page 27: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/27.jpg)
a horror story
![Page 28: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/28.jpg)
test "gets and updates many levels deep dependencies" do
Mix.Project.push DepsOnGitApp
in_fixture "no_mixfile", fn -‐>
Mix.Tasks.Deps.Get.run []
message = "* Getting git_repo (#{fixture_path("git_repo")})"
assert_received {:mix_shell, :info, [^message]}
message = "* Getting deps_on_git_repo (#{fixture_path("deps_on_git_repo")})"
assert_received {:mix_shell, :info, [^message]}
assert File.exists?("deps/deps_on_git_repo/mix.exs")
assert File.rm("deps/deps_on_git_repo/.fetch") == :ok
assert File.exists?("deps/git_repo/mix.exs")
assert File.rm("deps/git_repo/.fetch") == :ok
# Compile the dependencies
Mix.Tasks.Deps.Compile.run []
# Now update children and make sure it propagates
Mix.Tasks.Deps.Update.run ["git_repo"]
assert File.exists?("deps/deps_on_git_repo/.fetch")
assert File.exists?("deps/git_repo/.fetch")
# Compile git repo but unload it so...
Mix.Tasks.Deps.Compile.run ["git_repo"]
assert File.exists?("_build/dev/lib/git_repo/ebin")
Code.delete_path("_build/dev/lib/git_repo/ebin")
# Deps on git repo loads it automatically on compile
Mix.Task.reenable "deps.loadpaths"
Mix.Tasks.Deps.Compile.run ["deps_on_git_repo"]
assert File.exists?("_build/dev/lib/deps_on_git_repo/ebin")
end
after
purge [GitRepo, GitRepo.Mix]
end
Testing is good, but it’s not enough to test. This test is from the Elixir framework. This test is more insufficient tooling.
![Page 29: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/29.jpg)
test "gets and updates many levels deep dependencies" do
Mix.Project.push DepsOnGitApp
in_fixture "no_mixfile", fn -‐>
Mix.Tasks.Deps.Get.run []
message = "* Getting git_repo (#{fixture_path("git_repo")})"
assert_received {:mix_shell, :info, [^message]}
message = "* Getting deps_on_git_repo (#{fixture_path("deps_on_git_repo")})"
assert_received {:mix_shell, :info, [^message]}
assert File.exists?("deps/deps_on_git_repo/mix.exs")
assert File.rm("deps/deps_on_git_repo/.fetch") == :ok
assert File.exists?("deps/git_repo/mix.exs")
assert File.rm("deps/git_repo/.fetch") == :ok
# Compile the dependencies
Mix.Tasks.Deps.Compile.run []
# Now update children and make sure it propagates
Mix.Tasks.Deps.Update.run ["git_repo"]
assert File.exists?("deps/deps_on_git_repo/.fetch")
assert File.exists?("deps/git_repo/.fetch")
# Compile git repo but unload it so...
Mix.Tasks.Deps.Compile.run ["git_repo"]
assert File.exists?("_build/dev/lib/git_repo/ebin")
Code.delete_path("_build/dev/lib/git_repo/ebin")
# Deps on git repo loads it automatically on compile
Mix.Task.reenable "deps.loadpaths"
Mix.Tasks.Deps.Compile.run ["deps_on_git_repo"]
assert File.exists?("_build/dev/lib/deps_on_git_repo/ebin")
end
after
purge [GitRepo, GitRepo.Mix]
end
You can see that the test creator wants to do the right thing, but can’t.
![Page 30: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/30.jpg)
test "gets and updates many levels deep dependencies" do
Mix.Project.push DepsOnGitApp
in_fixture "no_mixfile", fn -‐>
Mix.Tasks.Deps.Get.run []
message = "* Getting git_repo (#{fixture_path("git_repo")})"
assert_received {:mix_shell, :info, [^message]}
message = "* Getting deps_on_git_repo (#{fixture_path("deps_on_git_repo")})"
assert_received {:mix_shell, :info, [^message]}
assert File.exists?("deps/deps_on_git_repo/mix.exs")
assert File.rm("deps/deps_on_git_repo/.fetch") == :ok
assert File.exists?("deps/git_repo/mix.exs")
assert File.rm("deps/git_repo/.fetch") == :ok
# Compile the dependencies
Mix.Tasks.Deps.Compile.run []
# Now update children and make sure it propagates
Mix.Tasks.Deps.Update.run ["git_repo"]
assert File.exists?("deps/deps_on_git_repo/.fetch")
assert File.exists?("deps/git_repo/.fetch")
# Compile git repo but unload it so...
Mix.Tasks.Deps.Compile.run ["git_repo"]
assert File.exists?("_build/dev/lib/git_repo/ebin")
Code.delete_path("_build/dev/lib/git_repo/ebin")
# Deps on git repo loads it automatically on compile
Mix.Task.reenable "deps.loadpaths"
Mix.Tasks.Deps.Compile.run ["deps_on_git_repo"]
assert File.exists?("_build/dev/lib/deps_on_git_repo/ebin")
end
after
purge [GitRepo, GitRepo.Mix]
end
But the framework is fighting against him.
![Page 31: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/31.jpg)
test "gets and updates many levels deep dependencies" do
Mix.Project.push DepsOnGitApp
in_fixture "no_mixfile", fn -‐>
Mix.Tasks.Deps.Get.run []
message = "* Getting git_repo (#{fixture_path("git_repo")})"
assert_received {:mix_shell, :info, [^message]}
message = "* Getting deps_on_git_repo (#{fixture_path("deps_on_git_repo")})"
assert_received {:mix_shell, :info, [^message]}
assert File.exists?("deps/deps_on_git_repo/mix.exs")
assert File.rm("deps/deps_on_git_repo/.fetch") == :ok
assert File.exists?("deps/git_repo/mix.exs")
assert File.rm("deps/git_repo/.fetch") == :ok
# Compile the dependencies
Mix.Tasks.Deps.Compile.run []
# Now update children and make sure it propagates
Mix.Tasks.Deps.Update.run ["git_repo"]
assert File.exists?("deps/deps_on_git_repo/.fetch")
assert File.exists?("deps/git_repo/.fetch")
# Compile git repo but unload it so...
Mix.Tasks.Deps.Compile.run ["git_repo"]
assert File.exists?("_build/dev/lib/git_repo/ebin")
Code.delete_path("_build/dev/lib/git_repo/ebin")
# Deps on git repo loads it automatically on compile
Mix.Task.reenable "deps.loadpaths"
Mix.Tasks.Deps.Compile.run ["deps_on_git_repo"]
assert File.exists?("_build/dev/lib/deps_on_git_repo/ebin")
end
after
purge [GitRepo, GitRepo.Mix]
end
Chaotic!
We are going to stamp this chaotic. It violates principles of coupling and single purpose. Also, the reporting can’t help us out as much as it should
![Page 32: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/32.jpg)
Shouldi
+ Fast+ Pretty Assertions+ Templates-Code
- Not Dry- Chaotic Beautiful ± Language / Syntax
![Page 33: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/33.jpg)
Blacksmith
+ Fast+ Pretty Assertions+ Templates-Code and Data
- Not Dry Data- Chaotic Beautiful Data± Language / Syntax
![Page 34: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/34.jpg)
Test all of your code with beautiful, dry, fast tests
Beautiful is important.
![Page 35: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/35.jpg)
Tests arefirst class citizens
You see,
![Page 36: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/36.jpg)
Language Matters
Said another way, language shapes thought. Syntax shapes language.
![Page 37: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/37.jpg)
test "chat" do chat = Chat.create(...) assert something_about_chatend
Why do we get names like this over and over?Because the language of “test” isn’t strong enough.
The language is for the designers of the framework, not the test.
![Page 38: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/38.jpg)
test "chat" do chat = Chat.create(...) assert something_about_chatend
The word we use here
![Page 39: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/39.jpg)
test "chat" do chat = Chat.create(...) assert something_about_chatend
The word we use here
![Page 40: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/40.jpg)
test "should create chat" do chat = Chat.create(...) assert something_about_chatend
should language improves the thought process: single purpose experiment.
![Page 41: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/41.jpg)
should "create chat" do chat = Chat.create(...) assert something_about_chatend
Push this language into the framework and we’ll be reminded to give all tests better namesand a single purpose.
![Page 42: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/42.jpg)
One Experiment,Multiple Measurements
Our overarching philosophy: one experiment, multiple measurements.
![Page 43: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/43.jpg)
test "chat" do bucket = create_bucket assert %{__struct__: "Bucket"} = bucket assert Bucket.empty?(bucket)
Bucket.add(bucket, 1) assert bucket.contents == [1]end
Multiple experiments, Multiple measurements
Tightly coupled, encourages abuse.
![Page 44: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/44.jpg)
setup context do assign bucket: create_bucketend should "create struct bucket", context do assert %{__struct__: "Bucket"} = context.bucketend should "be empty", context do assert Bucket.empty?(bucket)end should "add to bucket", context do Bucket.add(bucket, 1) assert bucket.contents == 1end should "remove from bucket", context ...
![Page 45: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/45.jpg)
setup context do assign bucket: create_bucketend should "create struct bucket", context do assert %{__struct__: "Bucket"} = context.bucketend should "be empty", context do assert Bucket.empty?(bucket)end should "add to bucket", context do Bucket.add(bucket, 1) assert bucket.contents == 1end should "remove from bucket", context ...
Our Experiment:) / :(
This is a compromise. It will allow us to tailor some concepts in advance of changes in exunit
![Page 46: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/46.jpg)
setup context do assign bucket: create_bucketend should "create struct bucket", context do assert %{__struct__: "Bucket"} = context.bucketend should "be empty", context do assert Bucket.empty?(bucket)end should "add to bucket", context do Bucket.add(bucket, 1) assert bucket.contents == 1end should "remove from bucket", context ...
We can improve...these should blocks are sometimes patterns that can be expanded through macros
![Page 47: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/47.jpg)
setup context do assign bucket: create_bucketend should_match_key :bucket, %{ __struct__: "Bucket" }should_match_key :bucket, %{ contents: [] }
should "add to bucket", context do Bucket.add(bucket, 1) assert bucket.contents == 1end should "remove from bucket", context ...
In both forms, we have one experiment and multiple measurements.
![Page 48: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/48.jpg)
Tests the context.
should_have_keyshould_match_key
Or tests for Plug connection.
should_respond_with :successshould_render_template :index
Or any framework specific matchers...
In both forms, we have one experiment and multiple measurements.
We are selling our soul here... macros instead of functions.
![Page 49: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/49.jpg)
Tests the context.
should_have_keyshould_match_key
Or tests for Plug connection.
should_respond_with :successshould_render_template :index
Or any framework specific matchers...
Continues on FailHalts on Error
In both forms, we have one experiment and multiple measurements.
We are selling our soul here... macros instead of functions.
![Page 50: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/50.jpg)
Business apps need Beautiful Test Data
![Page 51: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/51.jpg)
Business apps need Beautiful Test Data
Remember, tests are first class citizens
![Page 52: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/52.jpg)
Elixir makes Beautiful Test Data
![Page 53: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/53.jpg)
Elixir makes Beautiful Test Datauntil things get real
PersistenceDifferent formats JSON, structs, maps# of attributes
![Page 54: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/54.jpg)
Elixir makes Beautiful Test Datauntil things get real
Persistence
Formats
Number of
Attributes
Different Defaults
Per Test
Lists
PersistenceData issues can swallow tests
![Page 55: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/55.jpg)
Blacksmith
Mostly just a functional library with a few key macros
Create structured data for tests
![Page 56: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/56.jpg)
Blacksmith Templates
![Page 57: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/57.jpg)
defmodule Forge do use Blacksmith register :user, name: Faker.Name.first_name, email: Sequence. next(:email, &"test#{&1}@example.com"), description: Faker.Lorem.sentence, roles: [], always_the_same: "string"
register :admin, [prototype: user], roles: ["admin"]end
Faker is a library that creates fake data
![Page 58: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/58.jpg)
defmodule Forge do use Blacksmith register :user, name: Faker.Name.first_name, email: Sequence. next(:email, &"test#{&1}@example.com"), description: Faker.Lorem.sentence, roles: [], always_the_same: "string"
register :admin, [prototype: user], roles: ["admin"]end
![Page 59: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/59.jpg)
defmodule Forge do use Blacksmith register :user, name: Faker.Name.first_name, email: Sequence. next(:email, &"test#{&1}@example.com"), description: Faker.Lorem.sentence, roles: [], always_the_same: "string"
register :admin, [prototype: user], roles: ["admin"]end
Maybe you have a database backed test that should be isolated
In that test, email must be unique
![Page 60: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/60.jpg)
defmodule Forge do use Blacksmith register :user, name: Faker.Name.first_name, email: Sequence. next(:email, &"test#{&1}@example.com"), description: Faker.Lorem.sentence, roles: [], always_the_same: "string"
register :admin, [prototype: :user], roles: ["admin"]end
Maybe some data should be based on other dataSecond form of the register function has options (in the second position)
![Page 61: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/61.jpg)
Blacksmith Config
![Page 62: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/62.jpg)
defmodule Blacksmith.Config do def save(repo, map) do repo.insert(map) end
def save_all(repo, list) do Enum.map(list, &repo.insert/1) endend
![Page 63: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/63.jpg)
Blacksmith Usage
![Page 64: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/64.jpg)
user = Forge.user
user = Forge.saved_user Models.User, name: "Will Override"
admin = Forge.admin
admin = Forge.admin_list 5
![Page 65: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/65.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 66: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/66.jpg)
To have dry tests,you need specialized setups with nested context
![Page 67: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/67.jpg)
Controller test logged in index show create configure admin users configure show logged out index show create
![Page 68: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/68.jpg)
Controller test logged in index show create configure admin users configure show logged out index show create
![Page 69: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/69.jpg)
Controller test logged in index show create configure admin users configure show logged out index show create
![Page 70: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/70.jpg)
Controller test logged in index show create configure admin users configure show logged out index show create
![Page 71: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/71.jpg)
test "Logged in admin user gets configure" do part = Forge.saved_part(...) conn = setup_connection admin = Forge.saved_admin( ... ) sign_in admin conn = get conn, :configure assert conn.status == 200end
test "Logged in user user gets configure" do part = Forge.saved_part(...) conn = setup_connection user = Forge.saved_user( ... ) sign_in user conn = get conn, :configure, assert conn.status == 301end
![Page 72: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/72.jpg)
test "Logged in admin user gets configure" do part = Forge.saved_part(...) conn = setup_connection admin = Forge.saved_admin( ... ) sign_in admin conn = get conn, :configure assert conn.status == 200end
test "Logged in user user gets configure" do part = Forge.saved_part(...) conn = setup_connection user = Forge.saved_user( ... ) sign_in user conn = get conn, :configure, assert conn.status == 301end
Too much duplication
![Page 73: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/73.jpg)
with "a part and a connection" do ...setup for a connection and a part
with "a logged in user" do ...setup for logged in user
tests for logged in user
with "a logged in admin" do ...make the user an admin
tests for logged in admin
Too much duplication
![Page 74: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/74.jpg)
with "a get to configure" do setup do assign conn: get( :configure, context.part.id) end
should_respond_with :success should_render_template :configureend
now the test is easy
![Page 75: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/75.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 76: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/76.jpg)
1. Integration matters
Jose, you crack me up.
We were batting some test code back and forth over skype and emails. here’s Jose’s example
![Page 77: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/77.jpg)
setup do ...end
test "make breakfast" do breakfast = make_the_toast breakfast assert breakfast.taste == :good breakfast = spread_the_cream breakfast assert breakfast.taste == good
breakfast = be_sexy breakfast ...end
No. This will deteriorate with time. But maybe it takes a long time to make toast. So...
![Page 78: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/78.jpg)
setup do ...end
test "make breakfast" do breakfast = make_the_toast breakfast assert breakfast.taste == :good breakfast = spread_the_cream breakfast assert breakfast.taste == good
breakfast = be_sexy breakfast ...end Multipurpose
We have all written this test. But we can also see this test deteriorate with time.
But maybe it takes a long time to make toast. So... we live with the consequences.
![Page 79: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/79.jpg)
setup do ... %{ breakfast: create_breakfast ...}end
...end
No. This will deteriorate with time. But maybe it takes a long time to make toast. So...
![Page 80: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/80.jpg)
setup...
def make_toast ...
def spread_cream breakfast do breakfast = spread_the_cream breakfast assert breakfast.taste == good breakfastend
def be_so_sexy ......should...
No. This will deteriorate with time. But maybe it takes a long time to make toast. So...
![Page 81: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/81.jpg)
def setup
def make_toast ...def spread_cream ...def be_so_sexy ......
test "make breakfast", context do context.breakfast |> make_toast |> spread_cream |> be_so_sexyend
Much better. Single purpose...The tooling can’t help as much as we would likeWant failures reported from make_toast
![Page 82: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/82.jpg)
Integration tests will be
![Page 83: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/83.jpg)
... step "make the toast", breakfast do breakfast = make_the_toast breakfast assert breakfast.taste == :good breakfast end
step "spread the cream", breakfast do ... end
step "be sexy", breakfast do ... endend
![Page 84: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/84.jpg)
2. Concurrency matters
Functional programming helps. Database backed tests: Allow data templates which guarantee unique attributes.
![Page 85: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/85.jpg)
3. Isolate the Database
![Page 86: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/86.jpg)
Blacksmith list as a Repository
![Page 87: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/87.jpg)
Directions
![Page 88: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/88.jpg)
In ShouldI
•Push experiments out of setup blocks, back into tests
•Matchers are macros
![Page 89: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/89.jpg)
Into ExUnit
•Nested Context
•Continue on Fail
•Assertion Customization
•Integration Tests into ExUnit
![Page 90: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/90.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 91: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/91.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 92: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/92.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 93: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/93.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 94: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/94.jpg)
Test all of your code with beautiful, dry, fast tests
![Page 95: Beautiful Tests - erlang-factory.comBeautiful Tests by Bruce A. Tate icanmakeitbe*er It’s good to be here... I almost wasn’t. Test all of your code with beautiful, dry, fast tests.](https://reader033.fdocuments.net/reader033/viewer/2022041605/5e33ed2227dd45710c0e5adf/html5/thumbnails/95.jpg)
should respond_with questions
Functional programming helps. Database backed tests: Allow data templates which guarantee unique attributes.