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
440
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
BEAM: The Perfect Fit for Networks
whatyouhide
1
120
Update from the Elixir team - 2022
whatyouhide
0
330
Elixir Sightseeing Tour
whatyouhide
0
310
Mint - Disrupting HTTP clients
whatyouhide
0
200
BEAM Architecture Handbook
whatyouhide
7
2.5k
The Evolution of a Language
whatyouhide
0
110
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
290
Papers we love: Elixir edition
whatyouhide
5
960
Update from the Elixir team - 2018
whatyouhide
2
4.4k
Other Decks in Programming
See All in Programming
Apple Vision Pro購入RTA 1泊3日弾丸ハワイツアー / RTA: Purchase Apple Vision Pro in Hawaii
yutailang0119
0
480
品質が高いコードって何?Rev2.1
ickx
1
390
私がエッジを使う理由
chimame
9
3.6k
プログラミングを楽しもう! / Enjoy Programming
chobishiba
1
700
期限が近づいてきた!Privacy Manifests対応
ryunakayama
5
3.1k
Catch Up with Swift 5.10
ojun9
1
450
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
4
970
sbt-assemblyにハマってDB接続できず時間が溶けた話
wakye5815
1
660
SmartHRにおけるプロダクトエンジニア/product_engineer_in_smarthr_20240227
saitoryc
5
180
Static Analysis Automation for Hunting Vulnerable Kernel Drivers
takahiro_haruyama
1
1.4k
Sementic Kernelのネイティブ関数について
tomokusaba
0
780
PHP8の機能を使って堅牢にコードを書く
fendo181
6
2k
Featured
See All Featured
Facilitating Awesome Meetings
lara
39
5.5k
Practical Orchestrator
shlominoach
180
9.6k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
8
8.2k
Into the Great Unknown - MozCon
thekraken
10
810
Adopting Sorbet at Scale
ufuk
66
8.5k
Building Your Own Lightsaber
phodgson
97
5.6k
A Tale of Four Properties
chriscoyier
150
22k
What's new in Ruby 2.0
geeforr
335
31k
Put a Button on it: Removing Barriers to Going Fast.
kastner
58
3k
Navigating Team Friction
lara
177
13k
Building a Scalable Design System with Sketch
lauravandoore
455
32k
Being A Developer After 40
akosma
56
580k
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