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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Andrea Leopardi
September 09, 2021
Programming
580
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
More Decks by Andrea Leopardi
See All by Andrea Leopardi
Agentic Elixir
whatyouhide
0
500
The Umbrella and the Range
whatyouhide
0
67
gen_statem - OTP's Unsung Hero
whatyouhide
2
350
The World is a Network (and We Are Just Nodes)
whatyouhide
1
260
BEAM: The Perfect Fit for Networks
whatyouhide
1
270
Update from the Elixir team - 2022
whatyouhide
0
460
Elixir Sightseeing Tour
whatyouhide
0
490
Mint - Disrupting HTTP clients
whatyouhide
0
310
BEAM Architecture Handbook
whatyouhide
7
3k
Other Decks in Programming
See All in Programming
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
160
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
200
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
OSINT for SRE: 学術論文とポストモーテムから探る システム障害の共通パターン / SRE NEXT 2026
tomoyk
1
3.5k
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.4k
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
190
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
160
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
110
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
140
act2-costs.pdf
sumedhbala
0
110
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
150
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
5.8k
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
18k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Building AI with AI
inesmontani
PRO
1
1.1k
Writing Fast Ruby
sferik
630
63k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
210
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
180
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
420
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
320
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
450
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