Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Testing Asynchronous OTP
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Andrea Leopardi
September 09, 2021
Programming
590
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Transcript
68 slides
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
More Decks by Andrea Leopardi
See All by Andrea Leopardi
Agentic Elixir
whatyouhide
0
640
The Umbrella and the Range
whatyouhide
0
78
gen_statem - OTP's Unsung Hero
whatyouhide
2
380
The World is a Network (and We Are Just Nodes)
whatyouhide
1
270
BEAM: The Perfect Fit for Networks
whatyouhide
1
280
Update from the Elixir team - 2022
whatyouhide
0
470
Elixir Sightseeing Tour
whatyouhide
0
510
Mint - Disrupting HTTP clients
whatyouhide
0
320
BEAM Architecture Handbook
whatyouhide
7
3.1k
Other Decks in Programming
See All in Programming
우리의 Nitro Modules는 당신의 Turbo Modules보다 아름답다
l2hyunwoo
0
260
Getting Started with Vibe Coding
miccheng
0
220
どうしても Eloquent でリポジトリパターンをやりたいんだ #phpcon_niigata / phpcon-niigata-2026
shogogg
0
140
クラウドゲーミングのパフォーマンス最適化に挑む / Cloud Gaming Performance Tuning
vivion
0
330
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
310
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
230
はじめてのPLATEAU
nokonoko1203
1
650
Goコンパイラを作ってGoをもっと理解する / Build a Go compiler to better understand Go
ikura_hamu
0
130
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.9k
Enforcing Your Architecture with Unit Tests in the AI Era (Swift Connection X)
steliosf
PRO
1
170
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
370
ローカルLLMの基本と近況 2611 / Local LLM basics and recent situation 2611
kishida
2
360
Featured
See All Featured
Balancing Empowerment & Direction
lara
6
1.4k
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
4
1.2k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
530
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.2k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
1
240
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Skip the Path - Find Your Career Trail
mkilby
1
290
The World Runs on Bad Software
bkeepers
PRO
72
12k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.7k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
560
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k