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
0
440
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
BEAM: The Perfect Fit for Networks
whatyouhide
1
130
Update from the Elixir team - 2022
whatyouhide
0
330
Elixir Sightseeing Tour
whatyouhide
0
320
Mint - Disrupting HTTP clients
whatyouhide
0
200
BEAM Architecture Handbook
whatyouhide
7
2.5k
The Evolution of a Language
whatyouhide
0
110
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
290
Papers we love: Elixir edition
whatyouhide
5
970
Update from the Elixir team - 2018
whatyouhide
2
4.4k
Other Decks in Programming
See All in Programming
ONE WEDGE_company_guide
1wedge_one
0
480
AWS Application Composerで始める、 サーバーレスなデータ基盤構築 / 20240406-jawsug-hokuriku-shinkansen
kasacchiful
1
260
大規模Reactアプリのリアーキテクチャ~8万行のTanStack Query移行の軌跡~
kj455
4
960
Java 22 Overview
kishida
1
180
VS Code をプロダクトにどう取り込むか
onomax
1
360
Git Lint
bkuhlmann
4
750
"config" ってなんだ? / What is "config"?
okashoi
0
240
Azure OpenAI Serviceのプロンプトエンジニアリング入門
tomokusaba
3
710
Netty Chicago Java User Group 2024-04-17
sullis
0
180
Code Reviews
bkuhlmann
4
890
Snowflakeで眠ったデータを起こそう!
estie
0
120
Let's learn code review
riofujimon
2
340
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
60
14k
Documentation Writing (for coders)
carmenintech
60
3.9k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
18
6.9k
Designing on Purpose - Digital PM Summit 2013
jponch
110
6.5k
The Cult of Friendly URLs
andyhume
74
5.7k
How STYLIGHT went responsive
nonsquared
92
4.8k
For a Future-Friendly Web
brad_frost
172
9k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
Into the Great Unknown - MozCon
thekraken
10
990
Designing Dashboards & Data Visualisations in Web Apps
destraynor
226
51k
How to name files
jennybc
65
93k
The MySQL Ecosystem @ GitHub 2015
samlambert
243
12k
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