Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
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
540
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
The Umbrella and the Range
whatyouhide
0
28
gen_statem - OTP's Unsung Hero
whatyouhide
2
290
The World is a Network (and We Are Just Nodes)
whatyouhide
1
240
BEAM: The Perfect Fit for Networks
whatyouhide
1
220
Update from the Elixir team - 2022
whatyouhide
0
440
Elixir Sightseeing Tour
whatyouhide
0
450
Mint - Disrupting HTTP clients
whatyouhide
0
280
BEAM Architecture Handbook
whatyouhide
7
2.9k
The Evolution of a Language
whatyouhide
0
180
Other Decks in Programming
See All in Programming
TestingOsaka6_Ozono
o3
0
180
안드로이드 9년차 개발자, 프론트엔드 주니어로 커리어 리셋하기
maryang
1
140
AI 駆動開発ライフサイクル(AI-DLC):ソフトウェアエンジニアリングの再構築 / AI-DLC Introduction
kanamasa
11
3.9k
Implementation Patterns
denyspoltorak
0
120
Vibe codingでおすすめの言語と開発手法
uyuki234
0
120
ELYZA_Findy AI Engineering Summit登壇資料_AIコーディング時代に「ちゃんと」やること_toB LLMプロダクト開発舞台裏_20251216
elyza
2
620
開発に寄りそう自動テストの実現
goyoki
2
1.4k
モデル駆動設計をやってみようワークショップ開催報告(Modeling Forum2025) / model driven design workshop report
haru860
0
280
re:Invent 2025 のイケてるサービスを紹介する
maroon1st
0
150
JETLS.jl ─ A New Language Server for Julia
abap34
2
460
Rubyで鍛える仕組み化プロヂュース力
muryoimpl
0
160
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
8
3.3k
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
304
21k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
81
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.3k
Mobile First: as difficult as doing things right
swwweet
225
10k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
120
How to Talk to Developers About Accessibility
jct
1
85
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
29
WENDY [Excerpt]
tessaabrams
8
35k
The Spectacular Lies of Maps
axbom
PRO
1
400
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
1
860
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