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
460
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
150
BEAM: The Perfect Fit for Networks
whatyouhide
1
140
Update from the Elixir team - 2022
whatyouhide
0
340
Elixir Sightseeing Tour
whatyouhide
0
350
Mint - Disrupting HTTP clients
whatyouhide
0
210
BEAM Architecture Handbook
whatyouhide
7
2.6k
The Evolution of a Language
whatyouhide
0
120
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
290
Papers we love: Elixir edition
whatyouhide
5
1k
Other Decks in Programming
See All in Programming
フロントエンドのテストからアクセシビリティをしれっと広めていく
nano72mkn
3
700
Swift Concurrencyとレースコンディション
objectiveaudio
1
380
プログラマのための音楽入門
cheebow
4
540
フロントエンドカンファレンス北海道2024 『小規模サイトでも使えるVite 〜HTMLコーディングをよりスマートに〜』長谷川広武(ハム)
h2ham
1
2.5k
RAGの回答精度評価用のQAデータセットを生成AIに作らせた話
kurahara
0
210
Amebaチョイス立ち上げの裏側 ~依存システムとの闘い~
daichi_igarashi
0
220
BasicBasic認証
sadnessojisan
5
2.5k
楽しく簡単に!QRコードの読み取り機能を実装しよう
penguinsan_pg
1
190
From Spring Boot 2 to Spring Boot 3 with Java 22 and Jakarta EE
ivargrimstad
0
940
Polars を Kaggle コンペで使ってみた(LMSYS Chatbot Arena)
kohecchi
1
360
Boost Your Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
1
930
Modular Monolith Go Server with GraphQL Federation + gRPC
110y
1
550
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
125
16k
Producing Creativity
orderedlist
PRO
340
39k
No one is an island. Learnings from fostering a developers community.
thoeni
18
2.9k
Documentation Writing (for coders)
carmenintech
65
4.3k
Debugging Ruby Performance
tmm1
72
12k
Faster Mobile Websites
deanohume
304
30k
Thoughts on Productivity
jonyablonski
65
4.2k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
29
2.5k
Into the Great Unknown - MozCon
thekraken
28
1.4k
The Power of CSS Pseudo Elements
geoffreycrofte
71
5.2k
Writing Fast Ruby
sferik
623
60k
Making the Leap to Tech Lead
cromwellryan
128
8.8k
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