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
510
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
gen_statem - OTP's Unsung Hero
whatyouhide
1
190
The World is a Network (and We Are Just Nodes)
whatyouhide
1
200
BEAM: The Perfect Fit for Networks
whatyouhide
1
180
Update from the Elixir team - 2022
whatyouhide
0
390
Elixir Sightseeing Tour
whatyouhide
0
410
Mint - Disrupting HTTP clients
whatyouhide
0
240
BEAM Architecture Handbook
whatyouhide
7
2.8k
The Evolution of a Language
whatyouhide
0
140
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
320
Other Decks in Programming
See All in Programming
家族・子育て重視/沖縄在住を維持しながらエンジニアとしてのキャリアをどのように育てていくか?
ug
0
260
Day0 初心者向けワークショップ実践!ソフトウェアテストの第一歩
satohiroyuki
0
790
Code smarter, not harder - How AI Coding Tools Boost Your Productivity | Webinar 2025
danielsogl
0
100
これだけは知っておきたいクラス設計の基礎知識 version 2
masuda220
PRO
23
5.5k
S3静的ホスティング+Next.js静的エクスポート で格安webアプリ構築
iharuoru
0
220
DataStoreをテストする
mkeeda
0
270
snacks.nvim内のセットアップ不要なプラグインを紹介 / introduce_snacks_nvim
uhooi
0
390
技術選定を未来に繋いで活用していく
sakito
3
100
小田原でみんなで一句詠みたいな #phpcon_odawara
stefafafan
0
310
生成AIを使ったQAアプリケーションの作成 - ハンズオン補足資料
oracle4engineer
PRO
3
120
CRE Meetup!ユーザー信頼性を支えるエンジニアリング実践例の発表資料です
tmnb
0
610
リストビュー画面UX改善の振り返り
splcywolf
0
110
Featured
See All Featured
Designing Experiences People Love
moore
141
23k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
7
640
Product Roadmaps are Hard
iamctodd
PRO
52
11k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.3k
Adopting Sorbet at Scale
ufuk
75
9.3k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Fireside Chat
paigeccino
37
3.4k
We Have a Design System, Now What?
morganepeng
51
7.5k
A Tale of Four Properties
chriscoyier
158
23k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Java REST API Framework Comparison - PWX 2021
mraible
29
8.5k
The Invisible Side of Design
smashingmag
299
50k
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