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
38
gen_statem - OTP's Unsung Hero
whatyouhide
2
310
The World is a Network (and We Are Just Nodes)
whatyouhide
1
240
BEAM: The Perfect Fit for Networks
whatyouhide
1
240
Update from the Elixir team - 2022
whatyouhide
0
450
Elixir Sightseeing Tour
whatyouhide
0
460
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
grapheme_strrev関数が採択されました(あと雑感)
youkidearitai
PRO
1
210
AI駆動開発の本音 〜Claude Code並列開発で見えたエンジニアの新しい役割〜
hisuzuya
4
500
DevinとClaude Code、SREの現場で使い倒してみた件
karia
1
1k
今更考える「単一責任原則」 / Thinking about the Single Responsibility Principle
tooppoo
3
1.6k
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
tasukuwatanabe
2
100
Codex の「自走力」を高める
yorifuji
0
1.2k
AWS Infrastructure as Code の新機能 2025 総まとめ 〜SA 4人による怒涛のデモ祭り〜
konokenj
10
3.3k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
210
nilとは何か 〜interfaceの構造とnil!=nilから理解する〜
kuro_kurorrr
3
1.9k
手戻りゼロ? Spec Driven Developmentとは@KAG AI week
tmhirai
1
190
オブザーバビリティ駆動開発って実際どうなの?
yohfee
3
830
クライアントワークでSREをするということ。あるいは事業会社におけるSREと同じこと・違うこと
nnaka2992
1
330
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
HDC tutorial
michielstock
1
530
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.7k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
380
From π to Pie charts
rasagy
0
150
Ruling the World: When Life Gets Gamed
codingconduct
0
170
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
250
4 Signs Your Business is Dying
shpigford
187
22k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.2k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.4k
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