Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testing Asynchronous OTP
Search
Andrea Leopardi
September 09, 2021
Programming
1
520
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
gen_statem - OTP's Unsung Hero
whatyouhide
2
250
The World is a Network (and We Are Just Nodes)
whatyouhide
1
220
BEAM: The Perfect Fit for Networks
whatyouhide
1
200
Update from the Elixir team - 2022
whatyouhide
0
400
Elixir Sightseeing Tour
whatyouhide
0
420
Mint - Disrupting HTTP clients
whatyouhide
0
250
BEAM Architecture Handbook
whatyouhide
7
2.8k
The Evolution of a Language
whatyouhide
0
160
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
330
Other Decks in Programming
See All in Programming
Blazing Fast UI Development with Compose Hot Reload (droidcon New York 2025)
zsmb
1
220
AWS CDKの推しポイント 〜CloudFormationと比較してみた〜
akihisaikeda
3
310
Result型で“失敗”を型にするPHPコードの書き方
kajitack
4
380
LINEヤフー データグループ紹介
lycorp_recruit_jp
0
890
datadog dash 2025 LLM observability for reliability and stability
ivry_presentationmaterials
0
110
地方に住むエンジニアの残酷な現実とキャリア論
ichimichi
5
1.3k
エラーって何種類あるの?
kajitack
5
310
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
450
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
260
FormFlow - Build Stunning Multistep Forms
yceruto
1
190
Team operations that are not burdened by SRE
kazatohiei
1
210
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
160
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
490
Agile that works and the tools we love
rasmusluckow
329
21k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
930
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Practical Orchestrator
shlominoach
188
11k
Site-Speed That Sticks
csswizardry
10
660
Designing for Performance
lara
609
69k
Speed Design
sergeychernyshev
32
1k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Transcript
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
defmodule RollingAverage do use GenServer def start_link(limit), do: # ...
def add(pid, n), do: # ... def average(pid), do: # ... end
None
None
test "add/2" do {:ok, pid} = RollingAverage.start_link() RollingAverage.add(pid, 3) #
Now what? end
None
test "add/2 and average/1" do {:ok, pid} = RollingAverage.start_link(2) RollingAverage.add(pid,
3) RollingAverage.add(pid, 4) assert RollingAverage.average(pid) == 3.5 RollingAverage.add(pid, 5) assert RollingAverage.average(pid) == 4.5 end
None
defmodule RollingList do def new(limit), do: {limit, []} def add({limit,
list}, n), do: # ... def average({_limit, list}), do: # ... end
test "add/2" do rolling_list = RollingList.new(2) assert RollingList.add(rolling_list, 3) ==
{_limit = 2, [3]} end
None
test "add/2" do {:ok, pid} = RollingAverage.start_link(2) RollingAverage.add(pid, 3) state
= :sys.get_state(pid) assert state == {_limit = 2, [3]} end
None
None
test "add/2 and average/1" do {:ok, pid} = start_supervised( {RollingAverage,
_limit = 2} ) # Same as before end
None
def background_work do Task.start(fn -> do_something() end) end
None
None
def background_work(parent, ref) do Task.start(fn -> do_something() send(parent, {ref, :done})
end) end
test "background_work/0" do ref = make_ref() background_work(self(), ref) assert_receive {^ref,
:done} end
None
def background_work do Task.start(fn -> :ok = twitter_module.post() end) end
test "background_work/0" do parent = self() ref = make_ref() Mox.expect(TwitterMock,
:post, fn -> send(parent, ref) :ok end) background_work() assert_receive ^ref end
None
defmodule WeatherChecker do use GenServer def init(_) do :timer.send_interval(5000, self(),
:tick) end def handle_info(:tick, _) do check_weather() end end
test "checking weather periodically" do {:ok, _pid} = WeatherChecker.start_link() Process.sleep(5000
* 1.5) assert weather_checked?() end
None
defmodule WeatherChecker do use GenServer def init(_) do :timer.send_interval(5000, self(),
:tick) end def tick(pid), do: send(pid, :tick) def handle_info(:tick, _) do check_weather() end end
test "checking weather periodically" do {:ok, pid} = WeatherChecker.start_link() WeatherChecker.tick(pid)
assert weather_checked?() end
defmodule WeatherChecker do use GenServer def init(:interval) do :timer.send_interval(5000, self(),
:tick) end def init(:manual) do # No send_interval end end
None
@mix_env Mix.env() def start(_type, _args) do Supervisor.start_link(children(@mix_env), ...) end defp
children(:test), do: [...] defp children(_env), do: [WeatherChecker | ...]
None
None
None
None
test "cleanup after crashes" do Process.flag(:trap_exit, true) {:ok, pid} =
start_supervised(MyServer) Process.exit(pid, :kill) assert cleanup_successful?() end
None
None
None
None
None
None
None
None
None
None