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
560
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
42
gen_statem - OTP's Unsung Hero
whatyouhide
2
310
The World is a Network (and We Are Just Nodes)
whatyouhide
1
250
BEAM: The Perfect Fit for Networks
whatyouhide
1
240
Update from the Elixir team - 2022
whatyouhide
0
450
Elixir Sightseeing Tour
whatyouhide
0
470
Mint - Disrupting HTTP clients
whatyouhide
0
290
BEAM Architecture Handbook
whatyouhide
7
2.9k
The Evolution of a Language
whatyouhide
0
190
Other Decks in Programming
See All in Programming
CS教育のDX AIによる育成の効率化
niftycorp
PRO
0
140
ふつうのRubyist、ちいさなデバイス、大きな一年 / Ordinary Rubyists, Tiny Devices, Big Year
chobishiba
1
480
AI駆動開発の本音 〜Claude Code並列開発で見えたエンジニアの新しい役割〜
hisuzuya
4
520
nuget-server - あなたが必要だったNuGetサーバー
kekyo
PRO
0
280
CDIの誤解しがちな仕様とその対処TIPS
futokiyo
0
220
ポーリング処理廃止によるイベント駆動アーキテクチャへの移行
seitarof
3
1.1k
20260315 AWSなんもわからん🥲
chiilog
2
160
maplibre-gl-layers - 地図に移動体たくさん表示したい
kekyo
PRO
0
290
Windows on Ryzen and I
seosoft
0
320
ロボットのための工場に灯りは要らない
watany
11
3k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
750
AWS×クラウドネイティブソフトウェア設計 / AWS x Cloud-Native Software Design
nrslib
16
3.3k
Featured
See All Featured
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
86
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
640
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.1k
For a Future-Friendly Web
brad_frost
183
10k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
100
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
Skip the Path - Find Your Career Trail
mkilby
1
85
エンジニアに許された特別な時間の終わり
watany
106
240k
ラッコキーワード サービス紹介資料
rakko
1
2.7M
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
We Have a Design System, Now What?
morganepeng
55
8k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.1k
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