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
shadcn/uiを使ってReactでの開発を加速させよう!
lef237
0
300
オニオンアーキテクチャを使って、 Unityと.NETでコードを共有する
soi013
0
370
“あなた” の開発を支援する AI エージェント Bedrock Engineer / introducing-bedrock-engineer
gawa
4
240
Beyond ORM
77web
11
1.6k
DevFest - Serverless 101 with Google Cloud Functions
tunmise
0
140
AWSのLambdaで PHPを動かす選択肢
rinchoku
2
390
ecspresso, ecschedule, lambroll を PipeCDプラグインとして動かしてみた (プロトタイプ) / Running ecspresso, ecschedule, and lambroll as PipeCD Plugins (prototype)
tkikuc
2
1.9k
テストコード書いてみませんか?
onopon
2
340
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
7
1.4k
情報漏洩させないための設計
kubotak
5
1.3k
PHPで学ぶプログラミングの教訓 / Lessons in Programming Learned through PHP
nrslib
4
1.1k
ESLintプラグインを使用してCDKのセオリーを適用する
yamanashi_ren01
2
240
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.5k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
173
51k
Unsuck your backbone
ammeep
669
57k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
A Tale of Four Properties
chriscoyier
157
23k
Thoughts on Productivity
jonyablonski
68
4.4k
Scaling GitHub
holman
459
140k
For a Future-Friendly Web
brad_frost
176
9.5k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
500
Optimizing for Happiness
mojombo
376
70k
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