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
480
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
180
BEAM: The Perfect Fit for Networks
whatyouhide
1
160
Update from the Elixir team - 2022
whatyouhide
0
370
Elixir Sightseeing Tour
whatyouhide
0
390
Mint - Disrupting HTTP clients
whatyouhide
0
230
BEAM Architecture Handbook
whatyouhide
7
2.7k
The Evolution of a Language
whatyouhide
0
130
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
310
Papers we love: Elixir edition
whatyouhide
5
1.1k
Other Decks in Programming
See All in Programming
Androidアプリのモジュール分割における:x:commonを考える
okuzawats
1
270
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
420
令和7年版 あなたが使ってよいフロントエンド機能とは
mugi_uno
10
5.1k
PSR-15 はあなたのための ものではない? - phpcon2024
myamagishi
0
400
Запуск 1С:УХ в крупном энтерпрайзе: мечта и реальность ПМа
lamodatech
0
940
生成AIでGitHubソースコード取得して仕様書を作成
shukob
0
630
AWS re:Invent 2024個人的まとめ
satoshi256kbyte
0
100
責務を分離するための例外設計 - PHPカンファレンス 2024
kajitack
9
2.3k
知られざるDMMデータエンジニアの生態 〜かつてツチノコと呼ばれし者〜
takaha4k
1
290
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
390
Amazon Nova Reelの可能性
hideg
0
190
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
7
1.4k
Featured
See All Featured
KATA
mclloyd
29
14k
BBQ
matthewcrist
85
9.4k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
192
16k
Visualization
eitanlees
146
15k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
230
52k
VelocityConf: Rendering Performance Case Studies
addyosmani
327
24k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Embracing the Ebb and Flow
colly
84
4.5k
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