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
2
220
The World is a Network (and We Are Just Nodes)
whatyouhide
1
210
BEAM: The Perfect Fit for Networks
whatyouhide
1
190
Update from the Elixir team - 2022
whatyouhide
0
400
Elixir Sightseeing Tour
whatyouhide
0
420
Mint - Disrupting HTTP clients
whatyouhide
0
240
BEAM Architecture Handbook
whatyouhide
7
2.8k
The Evolution of a Language
whatyouhide
0
150
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
320
Other Decks in Programming
See All in Programming
“技術カンファレンスで何か変わる?” ──RubyKaigi後の自分とチームを振り返る
ssagara00
0
120
Golangci-lint v2爆誕: 君たちはどうすべきか
logica0419
1
270
読書シェア会 vol.4 『ダイナミックリチーミング 第2版』
kotaro666
0
110
Serving TUIs over SSH with Go
caarlos0
0
710
eBPF超入門「o11yに使える」とは (20250424_eBPF_o11y)
thousanda
1
120
SwiftDataのカスタムデータストアを試してみた
1mash0
0
150
状態と共に暮らす:ステートフルへの挑戦
ypresto
3
1.2k
20250426 GDGoC 合同新歓 - GDGoC のススメ
getty708
0
110
UMAPをざっくりと理解 / Overview of UMAP
kaityo256
PRO
3
1.6k
リアーキテクチャの現場で向き合う 既存サービスの読み解きと設計判断
ymiyamu
0
130
파급효과: From AI to Android Development
l2hyunwoo
0
170
「理解」を重視したAI活用開発
fast_doctor
0
310
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
19k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
[RailsConf 2023] Rails as a piece of cake
palkan
54
5.5k
We Have a Design System, Now What?
morganepeng
52
7.6k
Writing Fast Ruby
sferik
628
61k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.5k
BBQ
matthewcrist
88
9.6k
Become a Pro
speakerdeck
PRO
28
5.3k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.7k
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