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
550
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
36
gen_statem - OTP's Unsung Hero
whatyouhide
2
300
The World is a Network (and We Are Just Nodes)
whatyouhide
1
240
BEAM: The Perfect Fit for Networks
whatyouhide
1
230
Update from the Elixir team - 2022
whatyouhide
0
440
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
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
7
1.1k
登壇資料を作る時に意識していること #登壇資料_findy
konifar
4
1.9k
Oxlint JS plugins
kazupon
1
1.1k
AIプロダクト時代のQAエンジニアに求められること
imtnd
1
430
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
1
330
NOT A HOTEL - 建築や人と融合し、自由を創り出すソフトウェア
not_a_hokuts
2
380
組織で育むオブザーバビリティ
ryota_hnk
0
190
FOSDEM 2026: STUNMESH-go: Building P2P WireGuard Mesh Without Self-Hosted Infrastructure
tjjh89017
0
190
15年目のiOSアプリを1から作り直す技術
teakun
0
420
AIと一緒にレガシーに向き合ってみた
nyafunta9858
0
320
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
190
ご飯食べながらエージェントが開発できる。そう、Agentic Engineeringならね。
yokomachi
1
210
Featured
See All Featured
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
230
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
14k
The Cost Of JavaScript in 2023
addyosmani
55
9.5k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
270
Measuring & Analyzing Core Web Vitals
bluesmoon
9
760
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
300
Ethics towards AI in product and experience design
skipperchong
2
210
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
440
Visualization
eitanlees
150
17k
Building AI with AI
inesmontani
PRO
1
730
Writing Fast Ruby
sferik
630
62k
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