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
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
510
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
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
OSINT for SRE: 学術論文とポストモーテムから探る システム障害の共通パターン / SRE NEXT 2026
tomoyk
1
3.8k
初めてのKubernetes 本番運用でハマった話
oku053
0
130
20260623_Loop Engineeringで自分の分身の問い合わせBotを作る
ryugen04
0
220
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
150
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
140
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
2
1.5k
yield再入門 #phpcon
o0h
PRO
0
450
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
370
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
130
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
110
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
130
Featured
See All Featured
Thoughts on Productivity
jonyablonski
76
5.2k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
470
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
260
The Curse of the Amulet
leimatthew05
2
13k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
530
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
970
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Information Architects: The Missing Link in Design Systems
soysaucechin
0
1k
HDC tutorial
michielstock
2
750
Typedesign – Prime Four
hannesfritz
42
3.1k
エンジニアに許された特別な時間の終わり
watany
108
250k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.7k
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