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
470
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
The World is a Network (and We Are Just Nodes)
whatyouhide
0
150
BEAM: The Perfect Fit for Networks
whatyouhide
1
150
Update from the Elixir team - 2022
whatyouhide
0
350
Elixir Sightseeing Tour
whatyouhide
0
360
Mint - Disrupting HTTP clients
whatyouhide
0
210
BEAM Architecture Handbook
whatyouhide
7
2.6k
The Evolution of a Language
whatyouhide
0
120
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
300
Papers we love: Elixir edition
whatyouhide
5
1k
Other Decks in Programming
See All in Programming
Новый уровень ML-персонализации Lamoda: Как мы усилили ее в каталоге и перенесли на другие продукты
lamodatech
0
220
How to debug Xdebug... or any other weird bug in PHP
dunglas
2
1.2k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
11
1.5k
現場から考えるソフトウェアエンジニアリングの価値と実験
nomuson
1
130
PHPを書く理由、PHPを書いていて良い理由 / Reasons to write PHP and why it is good to write PHP
seike460
PRO
5
470
レイトレ合宿10 レンダラー紹介 / Renderer Introduction, Ray Tracing Camp 10
shocker_0x15
0
450
データフレームライブラリ徹底比較
daikikatsuragawa
2
110
2024-10-02 dev2next - Application Observability like you've never heard before
jonatan_ivanov
0
180
선언형 UI를 학습할 때 알아둬야하는 키워드들
l2hyunwoo
0
150
Програмиране с Rust, ФМИ, 2024
nikolads
0
110
.NET Aspireのクラウド対応検証: Azureと他環境での実践
ymd65536
1
530
C#および.NETに対する誤解をひも解く
ymd65536
0
310
Featured
See All Featured
Music & Morning Musume
bryan
46
6.1k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
1
310
How to train your dragon (web standard)
notwaldorf
87
5.6k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
7
590
Adopting Sorbet at Scale
ufuk
73
9k
Facilitating Awesome Meetings
lara
49
6k
Happy Clients
brianwarren
97
6.7k
Testing 201, or: Great Expectations
jmmastey
38
7k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
46
4.9k
From Idea to $5000 a Month in 5 Months
shpigford
381
46k
4 Signs Your Business is Dying
shpigford
180
21k
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